FreshRSS

🔒
❌ Über FreshRSS
Es gibt neue verfügbare Artikel. Klicken Sie, um die Seite zu aktualisieren.
Vor vorgesternDeveloper-Blog - Der Pragmatische Architekt

Per Anhalter durch die KI-Galaxie – LLM-Crashkurs Teil 4

Von Dr. Michael Stal
Under the Motor Hood of an LLM

Blick unter die Motorhaube

(Bild: generated by DALL-E)

Der letzte Teil der Serie betrachtet Reasoning-Modelle und gibt einen Ausblick auf die mögliche Zukunft der LLMs.

Ein Large Language Model (LLM) ist darauf ausgelegt, menschliche Sprache zu verarbeiten und zu generieren. Nach der grundlegenden Einführung von LLMs im ersten [1], den Hardwareanforderungen und vorab trainierten Modellen im zweiten [2] sowie den Architekturtypen im dritten Teil [3] geht es zum Abschluss um Reasoning-Modelle.

Fasten your seat belts!

Als LLMs denken lernten

Wer moderne LLMs wie Deepseek R1 oder OpenAI o3 nutzt, dürfte öfter Ausgaben wie "thinking" oder "reasoning" zu Gesicht bekommen. Das Sprachmodell ist also in der Lage, strukturiert und systematisch auf eine Anfrage zu reagieren. Daher nennt man sie Reasoning-Modelle.

Argumentationen beziehungsweise Schlussfolgerungen in Large Language Models werden durch verschiedene Techniken umgesetzt, die ihre Fähigkeit verbessern, komplexe Probleme in handhabbare Schritte zu zerlegen und logische Erklärungen zu liefern. Zu den wichtigsten Methoden gehören:

  • Chain-of-Thought-Prompting (CoT) beinhaltet das Training von LLMs, damit diese schrittweise Erklärungen für ihre Antworten generieren, was ihnen hilft, menschenähnliche Denkprozesse zu imitieren.
  • Supervised Fine-Tuning (SFT) und Reinforcement Learning: Techniken wie STaR (Self-Taught Reasoner) verwenden Reinforcement Learning, um Modelle für die Generierung korrekter Argumentationsschritte zu belohnen, die sich dann für das SFT verwenden lassen.
  • Prompt-Engineering: Strategien wie Active Prompt und Chain of Thought setzen LLM-Entwickler ein, um Argumentation von LLMs zu fördern, indem das LLM die Eingabe so strukturiert, dass es in der Lage ist, schrittweise zu "denken".

Diese Methoden zielen darauf ab, die Fähigkeit von LLMs zur Argumentation zu verbessern und transparente Denkprozesse bereitzustellen, obwohl Experten den Umfang, in dem sie tatsächlich argumentieren, weiterhin diskutieren.

Chain-of-Thought-(CoT)-Prompting verbessert die Argumentationsfähigkeiten von Large Language Models, indem es sie dazu anregt, komplexe Aufgaben in eine Reihe logischer Schritte zu zerlegen. Dieser Ansatz spiegelt menschliches Denken wider und ermöglicht es Modellen, Probleme systematischer und transparenter anzugehen. Zu den wichtigsten Vorteilen gehören:

  • Verbesserte Genauigkeit: Durch die Konzentration auf einen Schritt nach dem anderen können LLMs genauere Ergebnisse liefern, insbesondere bei komplexen Aufgaben wie mathematischem Problemlösen und logischem Denken.
  • Verbesserte Erklärbarkeit: CoT-Prompts bieten einen klaren Einblick in die Art und Weise, wie das Modell zu seinen Schlussfolgerungen gelangt, was das Vertrauen und das Verständnis für AI-Ausgaben verbessert.
  • Reduzierte Halluzinationen: Durch die Führung des Modells mit strukturierten Argumentationsschritten hilft CoT-Prompting, Fehler und Halluzinationen in den Antworten von LLMs zu reduzieren.

Fazit: Die Zukunft der LLMs

Große Sprachmodelle haben das Feld der natürlichen Sprachverarbeitung revolutioniert und ermöglichen Anwendungen wie Sprachübersetzung, Textzusammenfassung und Chatbots. Die Zukunft der LLMs ist aufregend, mit möglichen Anwendungen in Bereichen wie Bildung, Gesundheitswesen und Unterhaltung.

Eine innovative Lösung ist die Einführung von MoE-Verfahren (MoE = Mixture of Experts) in LLMs. Diese Modelle bestehen aus LLM-Komponenten, von denen jedes auf einer gewissen Domäne spezialisiert ist. Durch einen Gating-Mechanismus leitet das Modell Benutzeranfragen an die jeweils passende LLM-Komponente weiter.

Unter Agentic AI sind LLM-Agenten zu verstehen, die in der Lage sind, auf ihre Umgebung zuzugreifen, etwa um Funktionen zu starten oder die UI zu bedienen.

Multi-Agent-Systeme enthalten unterschiedliche LLM-Agenten, die ihrerseits verschiedene Rollen innehaben und miteinander agieren, um eine gemeinsame Aufgabe zu lösen, was an das bereits genannte Mixture of Experts erinnert.

Inzwischen sind auch immer mehr multimodale Modelle verfügbar, die neben Text auch Bilder, Videos, Audios oder Symbole verstehen und/oder generieren können. Vision-Modellen kann man ein Bild vorlegen, um danach Fragen zu dem Bild zu stellen. Einige Modelle erlauben die Eingabe von Prompts über gesprochene Sprache statt über Text. Modelle wie OpenAI Sora generieren realistische Videos aus Sprach-Prompts. Midjourney, DALL-E und ähnliche Modelle können Bilder aus Benutzeranforderungen (Prompts) erzeugen. Die Architektur der Modelle ähnelt der in diesem Artikel vorgestellten Architektur sehr stark. Nur dass die Modelle neben Text-Tokens auch andere Elemente wie Pixelsegmente verarbeiten und generieren können.

In Anbetracht dieser rasanten Entwicklung ist es essenziell, sich als Entwicklerin oder Nutzer intensiv mit dem Thema LLM und Generative AI zu beschäftigen. Ebenso wichtig sollte es sein, die neuen LLM-Technologien kritisch zu hinterfragen, speziell was ihre Auswirkungen auf unser Leben und unsere Gesellschaft betrifft. Das gilt insbesondere in Bezug auf ethische Grundsätze und Werte. Nur wer die Technologien kennt und versteht, kann die Chancen und Risiken einschätzen und abwägen.

Zusätzliche Ressourcen

Für diejenigen, die mehr über LLMs erfahren möchten, sind hier einige zusätzliche Ressourcen:

Glossar

Hier ist ein Glossar einiger der in dieser Artikelserie verwendeten Begriffe:

  • LLM: Large Language Model
  • Tokenizer: Eine Komponente, die den Eingabetext in kleinere Einheiten namens Token zerlegt.
  • Embeddings: Numerische Darstellungen von Wörtern, Subwörtern oder Zeichen, die die semantische Bedeutung erfassen.
  • Encoder: Eine Komponente, die eine kontinuierliche Darstellung des Eingabetextes generiert.
  • Decoder: Eine Komponente, die Text basierend auf der Eingabe und der kontextualisierten Darstellung generiert.
  • Self-Attention: Ein Mechanismus, der es dem Modell ermöglicht, auf verschiedene Teile des Eingabetextes zu achten und eine kontextualisierte Darstellung zu generieren.
  • Cross-Attention: Ein Mechanismus, der es dem Modell ermöglicht, auf externe Informationen zu achten, z. B. den Eingabetext oder andere Modelle.
  • Vorab trainierte Modelle: Modelle, die ihre Schöpfer auf großen Datensätzen trainiert und für spezifische Aufgaben feinabgestimmt haben.
  • Kontextfenster: Die Menge an Eingabetext, die das Modell zu einem bestimmten Zeitpunkt betrachten kann.
  • Masken: Mechanismen, die das Modell daran hindern, auf bestimmte Teile des Eingabetextes zu achten.


URL dieses Artikels:
https://www.heise.de/-10296366

Links in diesem Artikel:
[1] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-1-10283768.html
[2] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-2-10296098.html
[3] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-3-10296358.html
[4] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-1-10283768.html
[5] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-2-10296098.html
[6] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-3-10296358.html
[7] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-2-10296098.html
[8] https://arxiv.org/abs/1706.03762
[9] https://huggingface.co/docs/transformers/index
[10] https://en.m.wikipedia.org/wiki/BERT_(language_model)
[11] https://huggingface.co/docs/transformers/model_doc/roberta
[12] https://arxiv.org/abs/1906.08237
[13] https://nlp.stanford.edu/
[14] mailto:rme@ix.de

Copyright © 2025 Heise Medien

Adblock test (Why?)

  • 21. März 2025 um 09:16

Per Anhalter durch die KI-Galaxie – LLM-Crashkurs Teil 3

Von Dr. Michael Stal
KI-generiertes Auto mit offener motorhaube und Datenstrukturen

Blick unter die Motorhaube

(Bild: generated by DALL-E)

Die Artikelserie zeigt die internen Mechanismen großer Sprachmodelle von der Texteingabe bis zur Textgenerierung.

Ein Large Language Modell (LLM) ist darauf ausgelegt, menschliche Sprache zu verarbeiten und zu generieren. Nach der grundlegenden Einführung von LLMs im ersten [1] und den Hardwareanforderungen und vorabtrainierten Modellen im zweiten Teil [2] geht es diesmal um unterschiedliche Architekturtypen.

Fasten your seat belts!

Architekturtypen von LLMs

Ein häufiges Missverständnis der Transformer-Architektur besteht darin, dass LLMs notwendig alle Teile dieser Architektur enthalten müssen. Das ist nicht der Fall. Stattdessen lassen sich in der Praxis die folgenden Architekturtypen unterscheiden:

Sequence-to-Sequence-Modelle (Seq-to-Seq) sind darauf ausgelegt, eine Eingabesequenz wie einen Satz auf eine Ausgabesequenz wie eine Übersetzung oder Antwort abzubilden. Sie implementieren die Transformer-Architektur und bestehen infolgedessen aus:

  • Encoder: wandelt die Eingabe in eine dichte Darstellung (Kontextvektor) um
  • Decoder: erzeugt die Ausgabesequenz schrittweise (Token für Token) unter Verwendung des Kontextvektors

Seq-to-Seq-Modelle werden häufig für Aufgaben wie maschinelle Übersetzung, Textzusammenfassung und Textgenerierung eingesetzt. Beispiele sind das ursprüngliche Transformer-Modell von Google und T5 (Text-to-Text Transfer Transformer).

Decoder-Only-Modelle: Modelle wie GPT (Generative Pre-trained Transformer) verwenden eine reine Decoder-Architektur. Sie sind darauf trainiert, das nächste Token in einer Sequenz vorherzusagen, was sie besonders effektiv für Textgenerierung und -vervollständigung macht. Diese Modelle glänzen bei offenen Aufgaben, besitzen jedoch kein bidirektionales Kontextverständnis.

Encoder-Only-Modelle: BERT (Bidirectional Encoder Representations from Transformers) ist ein Beispiel für ein reines Encoder-Modell. Es verarbeitet Eingabetext bidirektional und erfasst Kontext sowohl aus vorangehenden als auch nachfolgenden Token. BERT eignet sich ideal für Aufgaben wie Sentimentanalyse, Named-Entity Recognition und Frage-Antwort-Systeme, kann aber keinen Text direkt generieren.

Wer Sentimentanalyse nicht kennt: Hier soll das Modell die Grundstimmung wie positiv oder negativ eines Satzes analysieren. Zum Beispiel enthält "Ich finde diesen Artikel gut." eine positive Aussage.

Hybride Architekturen: Einige Modelle wie T5 kombinieren Encoder-Decoder-Architekturen für einen einheitlichen Ansatz. T5 behandelt jede NLP-Aufgabe als ein Text-zu-Text-Problem, bei dem sowohl Eingabe als auch Ausgabe Textsequenzen sind. Diese Flexibilität macht es für vielfältige Aufgaben wie Übersetzung, Zusammenfassung und Klassifizierung geeignet.

Training von LLMs

Um LLMs zu trainieren, braucht es zunächst Daten und davon eine ganze Menge mit ausreichender Qualität. Das Training erfolgt in drei Schritten.

  • Vorbereitung der Daten, wobei Daten aus verschiedenen Quellen stammen, etwa Bücher, Webseiten, Code, Wissenschaftstexte (z. B. The Pile, Common Crawl). Wichtig ist auch die Quantität der Daten. Moderne LLMs werden auf >1 Milliarde Gewichte trainiert.
  • Trainingsziel: Das Ziel des LLM ist die Next Token Prediction, also wie sich das nächste Wort vorhersagen lässt. Dafür gibt es autoregressives Training: Das Modell lernt, das nächste Token x_{t+1} aus dem gegebenen Kontext ( x_1, ..., x_t ) vorherzusagen.
  • Verlustfunktion: Aus der Kreuzentropie zwischen vorhergesagter und tatsächlicher Token-Verteilung ergibt sich der Vorhersagefehler.

Das Training optimiert die gewählten Gewichte, bis die Verlustfunktion nur noch verschwindend kleine Vorhersagefehler (die Minima der Verlustfunktion) zurückmeldet.

Zur Optimierung gibt es unterschiedliche Stellgrößen und Verfahren:

  • AdamW-Optimierer: verfolgt einen adaptiven Lernratenansatz. Das heißt, die Größe einzelner Lernschritte variiert, um möglichst schnell das Training durchzuführen und dabei gleichzeitig für möglichst kleine Fehler der Vorhersagen zu sorgen.
  • Batch-Größen können bis zu Millionen von Token pro Batch sein.
  • Hardware: Das Training dauert auf TPU/GPU-Clustern über Wochen/Monate und kostet von Millionen bis mehreren hundert Millionen Euro. Allein die dafür notwendige Hardwareinfrastruktur ist immens, ganz zu schweigen von deren Kosten.

Um das Training zu verbessern, hat es sich darüber hinaus als empfehlenswert herausgestellt, mit Dropouts zu arbeiten. Dropouts definieren für eine neuronale Schicht bzw. für ein neuronales Netzwerk, dass ein gewisser Prozentsatz zufällig ausgewählter Neuronen in einer Trainingsiteration inaktiv bleiben soll. Dadurch erhöht sich erfahrungsgemäß die Robustheit des Verfahrens.

Residual Connections in LLMs

In großen Sprachmodellen (LLMs) wie GPT, BERT oder T5 ist eine Residual Connection (manchmal auch Skip Connection) ein zentrales Element der Transformer-Architektur. Sie stabilisiert das Training und ermöglicht es dem Modell, effektiv über Dutzende oder Hunderte von Schichten hinweg zu lernen. Ohne Residual Connections wären moderne LLMs kaum effektiv trainierbar, insbesondere in großem Maßstab. Sie sind grundlegend für das "Deep" in Deep Learning bei Sprachmodellen!

Wie Residual Connections funktionieren:

  • Struktur der Transformer-Schicht: Jede Transformer-Schicht (z. B. Self-Attention- oder Feed-Forward-Sublayer) enthält eine Residual Connection. Die Eingabe der Schicht wird direkt zu ihrem Ausgang addiert: Ausgabe = LayerNorm(x) + Sublayer(x). Hier steht `Sublayer` für die Self-Attention oder das Feed-Forward-Neuronale-Netz (FFN), und `LayerNorm` bezeichnet die Layer-Normalisierung.
  • Zweck von Residual Connections: Eine Residual Connection reduziert verschwindende Gradienten. Durch den "Kurzschluss" (Shortcut) für Gradienten beim Rückwärtsdurchlauf (Back Propagation) verhindern Residual Connections, dass Gradienten in tiefen Netzwerken während des Trainings auf nahezu Null schrumpfen. Dadurch können wegen numerischer Fehler Situationen auftreten, aus denen beim Training suboptimale Ergebnisse resultieren. Eine Residual Connection ermöglicht des Weiteren tiefe Architekturen. LLMs haben oft Dutzende bis Hunderte von Schichten. Residual Connections machen das Training solch tiefer Modelle praktikabel, indem das Netzwerk kleine Anpassungen (Residuen) zur Eingabe lernt, anstatt komplette Transformationen. Nicht zuletzt merkt sich eine Residual Connection Informationen. Das ist entscheidend für Sprachaufgaben, bei denen rohe Eingaben (z. B. Wort-Embeddings) über viele Schichten hinweg relevant bleiben müssen.

Residual Connections sind somit aus folgenden Gründen in LLMs wichtig:

  • Stabilität beim Training: LLMs werden mit Milliarden von Parametern trainiert. Residual Connections sorgen für effiziente Gradientenausbreitung und verhindern instabiles Training.
  • Abhängigkeiten mit langer Reichweite: Sprachaufgaben erfordern das Verständnis von Beziehungen zwischen weit entfernten Token (z. B. in einem Absatz). Residual Connections helfen, Token-Informationen über Schichten hinweg zu bewahren.
  • Synergie mit Layer-Normalisierung: Die Kombination aus Residual Connections und Layer-Normalisierung glättet die Optimierung und beschleunigt die Konvergenz.

Wichtige LLMs mit Residual Connections beinhalten unter anderem:

  • GPT-3/4: Jede Transformer-Decoder-Schicht nutzt Residual Connections.
  • BERT: Encoder-Schichten verwenden Residual Connections für bidirektionalen Kontext.
  • T5: Kombiniert Encoder-Decoder-Architektur mit Residual Links in beiden Komponenten.
Inferenz (Textgenerierung)

Der Einsatz trainierter LLMs geschieht über Chatbots der Hersteller, über APIs oder für lokal verfügbare Modelle über Werkzeuge wie Ollama und llama.cpp.

In der sogenannten autoregressiven Decodierung erzeugt das Modell Schritt für Schritt neue Token:

  • Das LLM zerlegt die Eingabe des Benutzers in Token.
  • Das LLM sagt das nächste Token voraus.
  • Das LLM fügt das neue Token zur Eingabe für den nächsten Schritt hinzu.

Die genutzten Sampling-Strategien (= Tokenauswahlstrategien) umfassen dabei verschiedene Optionen:

  • Greedy Decoding wählt das Token mit der höchsten Wahrscheinlichkeit aus (oft repetitiv).
  • Beam Search verfolgt parallel mehrere Kandidatensequenzen.
  • Top-k / Top-p Sampling trifft eine stochastische Auswahl aus den k wahrscheinlichsten Token oder Token mit kumulativer Wahrscheinlichkeit p.

Der vom Nutzer beeinflussbare Parameter Temperatur kontrolliert die Zufälligkeit (hohe Temperatur kreativ, niedrige konservativ) der gewählten Token.

Zu beachten sind dabei Skalierungsgesetze und Modellgrößen wie:

  • Chinchilla-Optimalität: Die Leistung korreliert natürlich mit Modellgröße N, Datenmenge D und Rechenkapazität C.
  • Effizienz: Größere Modelle benötigen exponentiell mehr Daten und Verarbeitungszeit.
Finetuning, Knowledge Graphs, RAG

Normalsterbliche Nutzer von LLMs können natürlich mangels ausreichender finanzieller Mittel und Hardware keine eigenen LLMs trainieren, zumindest nicht große Frontier-Modelle wie die von OpenAI, Claude, Cohere, Meta, Google und Microsoft. Allerdings ist es möglich, die Gewichte eines Open-Source- oder Open-Weight-Modells finezutunen. Open-Weights-Modelle liefern zwar die Gewichte mit, aber im Gegensatz zu Open-Source-Modellen nicht die zum Training verwendeten Daten oder Workflows. In beiden Fällen ist es aber möglich, die meisten Gewichte des trainierten Modells einzufrieren, um danach mit eigenen Trainingsdaten die nicht eingefrorenen Gewichte zu trainieren. Das nennt man Transfer-Learning. Dazu gibt es verschiedene Werkzeuge für macOS (z. B. MLX), Linux und Windows (z. B. Unsloth). Vorteil dieses eher leichtgewichtigen Ansatzes ist der geringere Hardwarebedarf und Zeitaufwand, um LLMs mit neuen domänenspezifischen Daten anzureichern. Das ist bei kleineren Modellen auch für den "Heimgebrauch" machbar.

Durch Retrieval Augmented Generation lassen sich Inhalte von Embedding-Datenbanken und ein LLM kombiniert für Abfragen (Prompts) nutzen.

Durch Retrieval Augmented Generation lassen sich Inhalte von Embedding-Datenbanken und ein LLM kombiniert für Abfragen (Prompts) nutzen.

(Bild: Wikipedia [7])

Da Modelle immer nur die aktuellen Daten zum Zeitpunkt ihres Trainings beinhalten und meistens eine sehr breite Zahl von Domänen antrainiert bekommen, gibt es mehrere Möglichkeiten, nachträglich tagesaktuelle Daten oder domänenspezifische Daten auf Umwegen ins Modell "einzuschleusen":

RAG (Retrieval Augmented Generation): Die Benutzerin nutzt ein passendes LLM-Modell. Zusätzlich verwendet sie eine Vektordatenbank. In dieser speichert sie Embeddings. Die Generierung der Embeddings erfolgt mit Hilfe vorliegender Dokumente, die die Anwendung zunächst in Teile (Chunks) zerlegt, die Teile anschließend in Embeddings (Vektoren) umwandelt und dann in der Vektordatenbank speichert. Falls eine Benutzeranfrage eintrifft, sucht die Anwendung zunächst in der Datenbank nach zum Eingabe-Prompt ähnlichen Embeddings (z. B. mittels Cosinus-Ähnlichkeitssuche), übergibt diese mit einem dafür geeigneten Prompt an das LLM und liefert dessen Ausgabe nach optionaler Nachbearbeitung an den User zurück. Dafür ist freilich notwendig, dass RAG und LLM das gleiche Embedding-Modell verwenden. Natürlich kann ein RAG-System alternativ auch mit ElasticSearch nach passenden Informationen suchen. Letzteren Ansatz können Entwickler zusammen mit Websuchen dafür nutzen, um eine LLM-unterstützte Websuche zu implementieren. Der Dienst Perplexity ist hierfür ein interessantes Beispiel.

Knowledge Graphs: Modernere Ansätze nutzen eine Graph-Datenbank (z. B. Neo4j) aus Wissensgraphen (Knowledge Graphs), um Information strukturiert zu speichern. Bei RAG-Systemen handelt es sich hingegen bei den gespeicherten Embeddings in der Regel um unstrukturierte Daten. Strukturierte Daten führen erfahrungsgemäß zu weniger Halluzinationen und sind leichter zu analysieren. In der Zukunft könnten Wissensgraphen daher an Bedeutung gewinnen.

Quantisierung

Sie möchten ein LLM-Modell, das nicht in den Arbeitsspeicher ihrer GPU oder CPU passt, dennoch nutzen? Normalerweise speichern die Schichten eines LLM Gewichte und Bias-Vektoren in Form von 32-Bit-Gleitkommazahlen. Diese Präzision ist aber nicht immer notwendig. Quantisierung in Large-Language-Modellen bezeichnet den Prozess, bei dem die Präzision der Modellparameter reduziert wird, um die Modellgröße und den Rechenaufwand zu verringern. Dies geschieht durch die Umwandlung von hochpräzisen Datenformaten (z. B. 32-Bit-Gleitkommazahlen) in weniger präzise Formate (z. B. 8-Bit-Ganzzahlen). Dadurch können LLMs auf Hardware mit begrenzten Ressourcen ausgeführt werden, was zu schnelleren Inferenzen und geringerem Speicherverbrauch führt. Allerdings kann die Quantisierung die Genauigkeit der Modelle beeinträchtigen. In vielen Fällen ist der Genauigkeitsverlust durch Quantisierung verschmerzbar.

Wenn sie beispielsweise in Hugging Face nach Modellen suchen, dürften Sie auf seltsame Dateinamen für Modelle stoßen, etwa auf <modelname>….Q4_K_M. Endungen von LLM-Namen wie Q4_K_M enthalten wichtige Informationen über die Quantisierung und Optimierung des Modells. Hier ist eine detaillierte Erklärung:

  • Q4: Dies zeigt an, dass das Modell auf eine 4-Bit-Präzision quantisiert wurde. Quantisierung reduziert die Präzision der Modellgewichte von der typischen 32-Bit-Gleitkommadarstellung auf eine niedrigere Präzision, wie 4 Bit, um Speicherplatz zu sparen und die Inferenzgeschwindigkeit zu verbessern.
  • K: Dies bezieht sich auf die spezifische Quantisierungsmethode, die für bestimmte Teile des Modells verwendet wird, zum Beispiel die Aufmerksamkeitsmechanismen. Es beinhaltet oft die Optimierung des Kernels (K) für bessere Leistung.
  • M: Dieser Suffix zeigt typischerweise an, dass die Quantisierungsmethode selektiv angewendet wird, oft auf bestimmte Schichten wie Einbettungen oder Aufmerksamkeitsmechanismen, während andere in der höheren Präzision bleiben. Dieser Ansatz balanciert Leistung und Speicherbedarf.

Zusammenfassend bedeutet Q4_K_M, dass das Modell auf 4-Bit-Präzision quantisiert ist, wobei optimierte Kernelmethoden selektiv Anwendung finden, um die Leistung zu erhalten, während sich der Speicherbedarf reduziert.

Hier ein Überblick über gängige Kürzel der möglichen Quantisierungsstufen:

  • Q2 (2 Bit)
  • Q4 (4 Bit)
  • Q8 (8 Bit)
  • Q16 (16 Bit)
  • Q32 (32 Bit, typischerweise nicht quantisiert)
  • K: Dies könnte sich auf eine spezifische Kernel- oder Optimierungsmethode beziehen. Mögliche Variationen könnten unterschiedliche Kerneloptimierungen oder Techniken umfassen, aber spezifische Werte sind nicht standardisiert.
  • Für die verwendete Präzision gibt es drei Möglichkeiten: M (Gemischte Präzision): Nur eine Teilmenge der Schichten erfährt eine Quantisierung, F (Volle Präzision): Das Modell verwendet die volle Präzision sowie S (Selektive Quantisierung): Quantisierung findet nur für eine selektive Teilmenge der Schichten statt.

Mögliche Kombinationen könnten also sein:

  • Q2_K_M
  • Q4_K_F
  • Q8_K_S
  • Q16_K_M

Diese Kombinationen spiegeln somit unterschiedliche Quantisierungsstufen und Optimierungsstrategien wider. Die genauen Namenskonventionen können jedoch je nach spezifischer Implementierung oder Modellarchitektur variieren.

Hinzufügungen wie _0 oder _1 bezeichnen Versionen von Quantisierungsschemata, beispielsweise unterschiedliche Algorithmen oder Techniken.

Modelle und Formate

Im Umfeld von LLMs sind Modelle fast immer als GGUF/GGML-Dateien gespeichert. Auch Apple MLX unterstützt hauptsächlich das GGUF (GPT-Generated Unified Format) für Modelldateien, hat jedoch kürzlich eine begrenzte Unterstützung für Quantisierungsausgaben erhalten, was darauf hindeuten könnte, dass es indirekt mit anderen Formaten kompatibel ist. Es gibt jedoch keine explizite Erwähnung, dass MLX Formate außer GGUF für seine Kernoperationen nutzt.

Gängige Formate, die LLM-Anbieter im maschinellen Lernen und bei großen Sprachmodellen verwenden:

  • GGUF/GGML: Optimiert für effiziente Inferenz und weit verbreitet im Apple-Ökosystem.
  • ONNX (Open Neural Network Exchange): Ein Format zum Austausch von Modellen zwischen verschiedenen Frameworks.
  • TensorFlow SavedModel: Verwendet für TensorFlow-Modelle.
  • PyTorch-Modelldateien: z. B. .pt- oder .pth-Dateien.
  • Hugging-Face-Transformers-Modelle: Oft in einem spezifischen Format gespeichert, das für die Hugging-Face-Bibliothek optimiert ist.

Tensordateien .pt und .pth:

Diese Formate erleichtern den Austausch und die Bereitstellung von Modellen auf verschiedenen Plattformen und Frameworks. In PyTorch sind .pt und .pth Dateierweiterungen, die Entwickler häufig zum Speichern von Modellen verwenden. Es gibt keinen funktionalen Unterschied zwischen ihnen; beide lassen sich nutzen, um PyTorch-Modelle oder Tensoren mithilfe des Python-pickle-Moduls über torch.save() zu speichern. Die Wahl zwischen .pt und .pth ist weitgehend eine Frage der Konvention. Allerdings wird .pt gegenüber .pth empfohlen, da .pth mit Python-Pfadkonfigurationsdateien in Konflikt geraten kann.

Beide Erweiterungen funktionieren austauschbar mit den torch.save()- und torch.load()-Funktionen. Aber was genau ist in diesen Dateien eigentlich gespeichert?

Sie speichern typischerweise serialisierte Daten, oft Modellgewichte oder andere Python-Objekte, konkret:

  • Modellgewichte: Diese Dateien enthalten die erlernten Parameter (Gewichte und Bias/Verzerrungen) eines neuronalen Netzwerkmodells nach dem Training. Dies ermöglicht das Speichern und spätere Laden des Modells für Inferenz oder weiteres Training.
  • Andere Datenstrukturen: Neben Modellgewichten können .pt- oder .pth-Dateien andere Python-Objekte wie Dictionaries, Listen oder benutzerdefinierte Datenstrukturen speichern.
  • Zustandsdictionaries: Die Dateien enthalten oft ein Zustandsdictionary (state_dict), das die Modellparameter enthält.

Lightning-Checkpoints, die ebenfalls die Erweiterungen .pt oder .pth verwenden könnten, speichern umfassendere Informationen, darunter Modellzustand, Optimiererzustände, Lernrateplanungszustände, Callback-Zustände, Hyperparameter.

In einer .pt-Datei sind die Einträge nicht in einem menschenlesbaren Format gespeichert. Stattdessen verwendet PyTorch das Python-pickle-Modul, um Tensoren und andere Python-Objekte in ein binäres Format zu serialisieren.

Falls Sie sich über Kennzeichnungen wie "INSTRUCT" in den Modellnamen wundern, hier ein paar Erläuterungen dazu:

In LLM-Dateinamen gibt es verschiedene Namen, die auf spezifische Techniken oder Anwendungen hinweisen. Einige Beispiele sind:

  • INSTRUCT: Diese Modelle sind darauf trainiert, Anweisungen zu befolgen und kleine Programme auszuführen, was sie besonders nützlich für komplexe Aufgaben macht.
  • BASE: bezeichnet oft das grundlegende Modell ohne spezifische Feinabstimmung
  • FINE-TUNED: Modelle, die für spezifische Aufgaben oder Stile weiterentwickelt wurden
  • CHAT: Modelle, die für den Einsatz in Chatbots optimiert sind
  • QA (Question Answering): Modelle, die darauf spezialisiert sind, Fragen zu beantworten

Der letzte Teil dieser Blogserie wird Reasoning-Modelle vorstellen und einen Blick in die Zukunft der LLMs wagen.


URL dieses Artikels:
https://www.heise.de/-10296358

Links in diesem Artikel:
[1] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-1-10283768.html
[2] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-2-10296098.html
[3] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-1-10283768.html
[4] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-2-10296098.html
[5] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-3-10296358.html
[6] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-2-10296098.html
[7] https://en.wikipedia.org/wiki/Retrieval-augmented_generation#/media/File:RAG_diagram.svg
[8] mailto:rme@ix.de

Copyright © 2025 Heise Medien

Adblock test (Why?)

  • 14. März 2025 um 13:00

Per Anhalter durch die KI-Galaxie – LLM-Crashkurs Teil 2

Von Dr. Michael Stal
Under the Motor Hood of an LLM

Blick unter die Motorhaube

(Bild: Erstellt mit DALL-E)

Die Artikelserie zu den internen Mechanismen großer Sprachmodelle behandelt diesmal die benötigte Hardware und pretrained Models.

Ein Large Language Model (LLM) ist darauf ausgelegt, menschliche Sprache zu verarbeiten und zu generieren. Nach der grundlegenden Übersicht zu LLMs im ersten Teil [1] geht es dieses Mal um die Hardware-Anforderungen und unterschiedliche vorab trainierte Modelle.

Fasten your seat belts!

Benötigte Hardware

Am Rande eine Bemerkung zu Hardware-Anforderungen: In der Beschreibung ist zu erkennen, dass im LLM sowohl für das Training als auch für die Ausführung (Inferenz) komplexe mathematische Berechnungen mit Vektoren vorkommen. Auf diese sind GPU-Kerne und neuronale Prozessoren spezialisiert. Daher benötigen LLM-Entwicklerinnen und -Nutzer leistungsvolle TPUs oder GPUs mit möglichst viel RAM. Mit normalen CPUs und wenig Arbeitsspeicher kommt man nicht weit, außer für sehr kleine Modelle. In den Speicher der GPU müssen unter anderem der Kontext und die errechneten Gewichte des LLM passen. Letztere können bis zu mehreren Hundert Gigabyte umfassen, während der Kontext von einigen Kilobytes bis zu vielen Megabytes reicht. Das Modell Deepseek R1 weist 671 Milliarden Gewichte/Tensoren und damit einen Speicherbedarf von rund 500 Gigabyte auf; OpenAI-Modelle sollen teilweise über ein Terabyte benötigen. Dafür wären etwa mehrere GPU-Beschleuniger vom Typ Nvidia H100 notwendig. Folgerichtig können Entwickler nur beschränkt Modelle auf ihren lokalen Systemen trainieren und laufen lassen, etwa bei guter Hardware-Ausstattung Modelle mit bis zu 70 Milliarden Parametern.

Vorab trainierte Modelle: Die Macht des Transfer-Lernens

Vorab trainierte Modelle sind LLMs, die ihre Schöpfer auf großen Datensätzen trainiert und für spezifische Aufgaben feingetunt haben. Diese Modelle dienen als Ausgangspunkt für andere Aufgaben, um dem Modell zu ermöglichen, die während des Trainings gelernten Muster und Beziehungen zu nutzen. Beliebte vorab trainierte Modelltypen sind:

  • BERT (Bidirectional Encoder Representations from Transformers): ein vorab trainiertes Modell, das einen mehrschichtigen bidirektionalen Transformer-Encoder verwendet, um kontextualisierte Darstellungen von Wörtern im Eingabetext zu generieren.
  • RoBERTa (Robustly Optimized BERT Pretraining Approach): ein vorab trainiertes Modell, das eine modifizierte Version der BERT-Architektur und ein anderes Trainingsziel verwendet.
  • XLNet (Extreme Language Modeling): ein vorab trainiertes Modell, das eine Kombination von Autoencoding- und autoregressiven Techniken nutzt, um kontextualisierte Darstellungen von Wörtern im Eingabetext zu generieren.

Kontextfenster: Das Sichtfeld des Modells

Kontextfenster beziehen sich auf die Menge an Eingabetext, die das Modell zu einem bestimmten Zeitpunkt betrachten kann. Das haben wir schon im ersten Teil der Serie [6] betrachtet, soll aber hier nochmals Erwähnung finden. Das Kontextfenster kann fest oder dynamisch sein, je nach Modellarchitektur. Ein größeres Kontextfenster ermöglicht es dem Modell, mehr Kontext zu erfassen, erhöht aber auch den Rechenaufwand. Moderne LLMs haben Kontextlängen von ein paar tausend bis zu ein paar Millionen Tokens.

Masken: Die Augenbinden des Modells

Masken helfen, das Modell daran zu hindern, auf bestimmte Teile des Eingabetextes zu achten. Es gibt verschiedene Arten von Masken, darunter:

  • Padding-Masken dienen dazu, um das Modell daran zu hindern, auf Padding-Token zu achten, die zum Eingabetext hinzugefügt werden, um ihm eine feste Länge zu geben. Zu diesen Token gehört zum Beispiel das EoS-Token (End of Sequence).
  • Achtungsmasken verhindern im Modell, bestimmte Teile des Eingabetextes zu sehen, etwa zukünftige Token in einer Sequenz.
  • Kausale Masken sind nützlich, um das Modell daran zu hindern, auf zukünftige Token in einer Sequenz zu achten, und um dadurch zu ermöglichen, Text Token-weise zu generieren.

Anfangsverarbeitung einer Abfrage

Sobald man eine Abfrage (Prompt) in ein LLM eingibt, durchläuft die Abfrage die folgenden Schritte:

  • Tokenisierung: Die Implementierung zerlegt die Nutzeranfrage (Prompt) in eine Folge von Token, wie Wörter oder Subwörter.
  • Embedding-Erstellung: Jedes Token wandelt sich in eine numerische Darstellung, indem die Implementierung es durch eine Embedding-Schicht leitet.
  • Positionelle Codierung: Die Embeddings des Prompts verknüpft das Modell mit positionellen Codierungen, um die Reihenfolge der Token zu erhalten.

Danach führt das LLM die folgenden Schritte aus:

  • Self-Attention: Das Embedding des Prompts durchläuft eine Self-Attention-Schicht, um eine kontextualisierte Darstellung zu generieren.
  • Cross-Attention: Die kontextualisierte Darstellung durchläuft eine Cross-Attention-Schicht, um externe Informationen zu berücksichtigen, beispielsweise den Eingabetext oder andere Modelle.
  • Feed-Forward-Layer: Das LLM leitet die Ausgabe der Cross-Attention-Schicht danach durch mehrere Feed-Forward-Layer, um die Darstellung in eine höhere Ebene zu transformieren. Zweck: Der Layer fügt Nichtlinearität und Kapazität hinzu, um komplexe Muster zu lernen.
  • Kontextfenster: Die endgültige Ausgabe erzeugt das LLM durch Anwendung eines Kontextfensters. Es arbeitet auf der erwähnten höheren Ebene der Darstellung. Das erlaubt dem Modell, sich auf einen bestimmten Teil der Abfrage zu konzentrieren.
  • Maskierung: Letztlich erfolgt die Maskierung der endgültigen Ausgabe, um das Modell daran zu hindern, auf bestimmte Teile der Abfrage zu achten, wie auf Padding-Token.

Der nachfolgende Code demonstriert die Schritt-für-Schritt-Verarbeitung einer Abfrage, einschließlich Tokenisierung, Embedding-Erstellung, positioneller Codierung, Self-Attention, Cross-Attention, Feed-Forward-Layer, Kontextfenster und Maskierung.


import torch
from transformers import AutoModelForMaskedLM, AutoTokenizer

# Laden Sie das vorab trainierte Modell und den Tokenizer
modell = AutoModelForMaskedLM.from_pretrained("bert-base-uncased")
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")

# Definieren Sie eine Abfrage
abfrage = "Erläutere die Geschichte des Heise-Verlags."

# Tokenisieren Sie die Abfrage
eingabe = tokenizer(abfrage, return_tensors="pt")

# Erstellen Sie die Embeddings
embedded_abfrage = modell.embeddings(eingabe["input_ids"])

# Fügen Sie die positionale Kodierung hinzu
positionale_kodierung = modell.positional_encodings(embedded_abfrage)
embedded_abfrage = embedded_abfrage + positionale_kodierung

# Wenden Sie die Self-Attention an
kontextualisierte_darstellung = modell.self_attention(embedded_abfrage)

# Wenden Sie die Cross-Attention an
hoeher_ebene_darstellung = modell.cross_attention(kontextualisierte_darstellung)

# Wenden Sie die Feed-Forward-Layer an
transformierte_darstellung = modell.feed_forward_layers(hoeher_ebene_darstellung)

# Wenden Sie das Kontextfenster an
endgueltige_ausgabe = modell.context_window(transformierte_darstellung)

# Maskieren Sie die Ausgabe
antwort = modell.masking(endgueltige_ausgabe)

print(antwort)

Die folgenden Dateien erstellt oder modifiziert das Modell während der Ausführung:

  • modell.pth: die trainierte Modell-Datei
  • tokenizer.json: die Tokenizer-Konfigurationsdatei
  • abfrage.txt: die Eingabe-Abfrage-Datei
  • antwort.txt: die Ausgabe-Antwort-Datei

Hinweis: Dies ist ein stark vereinfachtes Beispiel. Reale Anwendungen mit LLMs sind in der Praxis viel komplexer und vielschichtiger.

In meinem nächsten Blogbeitrag gehe ich auf unterschiedliche Architekturtypen von LLMs ein.


URL dieses Artikels:
https://www.heise.de/-10296098

Links in diesem Artikel:
[1] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-1-10283768.html
[2] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-1-10283768.html
[3] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-2-10296098.html
[4] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-3-10296358.html
[5] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-2-10296098.html
[6] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-1-10283768.html
[7] mailto:rme@ix.de

Copyright © 2025 Heise Medien

Adblock test (Why?)

  • 06. März 2025 um 16:01

Per Anhalter durch die KI-Galaxie – LLM-Crashkurs Teil 1

Von Dr. Michael Stal
Under the Motor Hood of an LLM

Blick unter die Motorhaube

(Bild: generated by DALL-E)

Die Artikelserie zeigt die internen Mechanismen großer Sprachmodelle von der Texteingabe bis zur Textgenerierung.

Stellen Sie sich eine magische Wissensdatenbank vor, in der Einträge nicht nur statische Sammlungen von Wörtern sind, sondern lebendige Entitäten, die menschliche Texte verstehen und generieren können. Willkommen in der Welt der Large Language Models (LLMs), die die Grenzen der natürlichen Sprachverarbeitung auf verblüffende Weise erweitern. Als Softwareentwickler sind wir gerade dabei, eine faszinierende Reise zu beginnen, die uns durch die inneren Strukturen dieser linguistischen Mechanismen führt. Immerhin haben Large Language Models wie GPT-4, Claude oder Llama die KI-Landschaft in den letzten Jahren revolutioniert.

Fasten your Seat Belts!

Grundlagen von LLMs

Ein Large Language Modell ist eine Art künstliche Intelligenz (KI), die darauf ausgelegt ist, menschliche Sprache zu verarbeiten und zu generieren. Es handelt sich um ein Lernmodell, das tiefschichtige neuronale Netze verwendet, um Muster und Beziehungen innerhalb von Sprachdaten zu lernen. Das "Large" in LLM bezieht sich auf die enorme Menge an Trainingsdaten und die enorme Anzahl an Parametern, die sich als justierbare Knöpfe betrachten lassen und die das Modell verwendet, um Vorhersagen zu treffen.

LLMs basieren auf der Transformer-Architektur, die 2017 in „Attention Is All You Need [4]“ eingeführt wurde. Im Gegensatz zu RNNs oder CNNs nutzt der Transformer Self-Attention-Mechanismen, um Kontextbeziehungen zwischen allen Wörtern in einem Text parallel zu erfassen.

Schlüsselkomponenten des Transformers sind unter anderem:

  • Encoder-Decoder-Struktur (bei LLMs oft nur der Decoder)
  • Multi-Head Attention
  • Feed-Forward-Netzwerke
  • Residual Connections und Layer Normalization

Klingt alles wie böhmische Dörfer? Ich versuche, die Konzepte näher zu erläutern.

Die Transformer-Architektur besteht aus Encodern und Decodern, die wiederum aus neuronalen Netzen zusammengesetzt sind.

(Bild: Wikipedia)

Ein LLM setzt sich vereinfacht aus den folgenden Komponenten zusammen:

  • Tokenizer: Dies ist der Türsteher des Modells, der dafür verantwortlich ist, die Eingabetexte in kleinere Einheiten namens Tokens zu zerlegen. Tokens können Wörter, Subwörter (kleinere Einheiten innerhalb von Wörtern) oder sogar Zeichen sein.
  • Embeddings: Die Embeddings-Schicht ist der Ort, an dem die Magie beginnt. Sie wandelt die Eingabe-Tokens in numerische Darstellungen um, die man als Embeddings bezeichnet und die das Modell verstehen kann. Diese Embeddings erfassen die semantische Bedeutung der Token, sodass das Modell zwischen Wörtern mit ähnlichen Bedeutungen unterscheiden kann.
  • Encoder: Der Encoder ist das Gehirn des Modells, in dem die Magie passiert. Er nimmt die Embeddings und generiert eine kontinuierliche Darstellung des Eingabetextes, oft als "kontextualisierte Darstellung" bezeichnet. Diese Darstellung erfasst die Nuancen der Sprache, wie Syntax, Semantik und Kontext.
  • Decoder: Der Decoder ist die kreative Seite des Modells, die dafür verantwortlich ist, Text basierend auf der Eingabe und der kontextualisierten Darstellung zu generieren. Es verhält sich wie ein hoch entwickelter Sprachgenerator, der kohärente und kontextuell relevante Texte produzieren kann.
  • Trainingsziel: Das Trainingsziel ist das Leitprinzip des Modells, das definiert, was das Modell während des Trainings optimieren soll. Häufige Ziele sind maskiertes Sprachmodellieren (Vorhersage fehlender Token) und Vorhersage des nächsten Satzes (Vorhersage, ob zwei Sätze aufeinanderfolgen).

Jedes LLM besteht aus einem Stapel neuronaler Schichten – genau genommen aus Dutzenden bis Hunderten identischer Transformer-Schichten für eine hierarchische Merkmalsverarbeitung:

  • Frühe Schichten erfassen lokale Muster (z. B. Wortgruppen).
  • Tiefe Schichten modellieren globale Kontexte und Abstraktionen.

Beispiel: GPT-3 hat 96 Schichten, LLaMA 2 bis zu 70 Schichten.

Ziel eines Tokenizers ist die Umwandlung von Rohtext in diskrete Einheiten (Token). Dafür gibt es mehrere Methoden:

  • Byte-Pair Encoding (BPE): Kombiniert häufige Zeichenfolgen (z. B. „un“ und „happy“ zu „unhappy“).
  • WordPiece: Ähnlich BPE, optimiert für Subword-Einheiten.
  • SentencePiece: Verarbeitet Rohtext ohne Vor-Tokenisierung.

Beispiel: Der Satz „KI ist faszinierend!“ könnte in Tokens wie `["KI", " ist", " fas", "zin", "ierend", "!"]` zerlegt werden.

Embeddings: Die Bausteine der LLMs

Embeddings sind die Grundlage der LLMs, die es dem Modell ermöglichen, Tokens (Wörter, Subwörter oder Zeichen) als numerische Vektoren darzustellen. Jeder Token wird in einen hochdimensionalen Vektor (z. B. 768 oder 4096 Dimensionen) umgewandelt. Diese Vektoren lernt das Modell während des Trainings und erfasst die semantische Bedeutung der Eingabe-Token. Es gibt verschiedene Arten von Embeddings, darunter:

  • Wort-Embeddings stellen Wörter als Vektoren in einem hochdimensionalen Raum dar. Jedes Wort ist mit einem eindeutigen Vektor assoziiert, sodass das Modell zwischen Wörtern mit ähnlichen Bedeutungen unterscheiden kann. Die Vektoren bestehen aus reellen Zahlen und umfassen nicht selten mehrere Hundert Elemente. Jede Dimension repräsentiert eine von der AI gewählte Domäne, etwa Farbe, Tiergattung.
  • Subwort-Embeddings stellen Subwörter (kleinere Einheiten innerhalb von Wörtern) als Vektoren dar. Dies ermöglicht es dem Modell, die Nuancen der Wortmorphologie zu erfassen und unbekannte Wörter zu handhaben.
  • Zeichen-Embeddings stellen einzelne Zeichen als Vektoren dar. Dies ist nützlich für die Handhabung von Sprachen mit komplexen Schriftsystemen oder für die Modellierung von Zeichenmustern.

Wichtig an dieser Stelle ist, dass wir Entwickler die Dimensionen nicht selbst definieren. Das macht das Modell beim Training ganz ohne unser Zutun. Eine Dimension könnte etwa Farbe sein, eine andere Länge. Jedenfalls liegen ähnliche Begriffe wie "Kater" und "Katze" in dem mehrdimensionalen Vektorraum ganz nahe beieinander. Begriffe wie "Eiscreme" und "Weltall" liegen hingegen weit auseinander.

Positionelle Codierungen und Embeddings

Positionelle Codierungen, im Englischen als positional embeddings bezeichnet, spielen eine entscheidende Rolle bei LLMs, indem sie die Reihenfolge der Eingabe-Token erhalten. LLMs zerlegen den Eingabetext in eine Folge von Token und wandeln jedes Token in eine numerische Darstellung um. Allerdings geht bei dieser Umwandlung die Reihenfolge der Token verloren, die für das Verständnis des Kontexts und der Beziehungen zwischen Token essenziell ist. Um dieses Problem zu lösen, führt man positionelle Codierungen zu den embedded Token hinzu, um sich die Reihenfolge der Token zu merken. Das LLM lernt die positionellen Codierungen während des Trainings. Sie dienen dazu, die Position jedes Tokens in der Sequenz zu codieren. Dies ermöglicht es dem Modell, die Beziehungen zwischen Token und ihrer Position in der Sequenz zu verstehen.

Es gibt verschiedene Arten positioneller Codierungen:

  • Absolute positionelle Codierungen verwenden eine feste Codierung für jede Position in der Sequenz.
  • Relative positionelle Codierungen verwenden eine relative Codierung, die von der Distanz zwischen Token abhängt.
  • Gelernte positionelle Codierungen lernt das Modell während des Trainings. Sie lassen sich basierend auf der spezifischen Aufgabe und dem Datensatz anpassen.

Feed-Forward-Layer: Die Arbeitstiere der LLMs

Feed-Forward-Layer (vollständig verbundene Layer) sind die Arbeitstiere der LLMs. Sie nehmen die Embeddings als Eingabe und generieren eine kontinuierliche Darstellung des Eingabetextes. Feed-Forward-Layer bestehen aus:

  • Lineare Layer wenden eine lineare Transformation auf die Eingabe-Embeddings an, um dadurch eine neue Menge von Vektoren zu generieren.
  • Aktivierungsfunktionen wie ReLU (Rectified Linear Unit) oder GELU (Gaussian Error Linear Unit), führen Nichtlinearität in das Modell ein, um komplexe Muster und Beziehungen zu erfassen.

In Sätzen wie „Der Hund jagte die verschlagene Katze durch das ganze Haus. Sie konnte sich aber rechtzeitig verstecken“ kommen verschiedene Wörter vor, von denen jedes einzelne nicht einfach isoliert im Raum steht. Im ersten Satz bezieht sich „Hund“ unter anderem auf eine Tätigkeit „jagte“ und die gejagte „Katze“. Uns liegen also starke Verbindungen des Wortes „Hund“ zu zwei weiteren Wörtern im selben Satz vor. Jedes dieser Wortpaare definiert die Beziehung eines Wortes im Satz zu einem anderen. Diese Verbindungen können stärker oder schwächer sein. Ein LLM berechnet die Beziehungen für jedes Wort im Satz zu jedem anderen Wort im Satz. Das nennt sich Self-Attention. Sie bezeichnet, wie stark sich Token gegenseitig „beachten“.

Weil das LLM parallel an mehreren Stellen eines Textes die entsprechenden Attentions erstellt, haben wir es mit Multi-Head-Attentions zu tun. Ohne ausreichenden Weitblick gehen einem LLM allerdings wichtige satzübergreifende Beziehungen verloren. Würden LLMs also Text in Sätze zerlegen und jeden Satz für sich bearbeiten, ginge im zweiten Satz verloren, dass sich das „Sie“ auf „Katze“ im ersten Satz bezieht. Cross-Attention dient dazu, um Attention/Beziehungen auch über einen größeren Kontext festzustellen. Wichtig dabei ist: LLMs sind in der Größe des betrachteten Kontexts beschränkt. Je größer der Kontext, desto größer der benötigte Arbeitsspeicher. Die Kontextgrößen reichen von wenigen Kilobytes (ein paar Schreibmaschinenseiten) bis zu mehreren Megabytes (ganze Buchinhalte). Wenn das LLM bereits zu viel Kontextinformation gemerkt hat und der Speicher "überläuft", beginnt es vorangegangenen Kontext zu "vergessen".

Self-Attention ist ein Mechanismus, der es dem Modell ermöglicht, auf verschiedene Teile des Eingabetextes zu achten und eine kontextualisierte Darstellung zu generieren. Zu welchem anderen Wort hat das gerade betrachtete Wort die größte Beziehung (Attention).

Multi-Head-Attention ist ein Mechanismus, der es dem Modell ermöglicht, auf verschiedene Teile des Eingabetextes von geschiedenen Perspektiven gleichzeitig zu achten. Statt einer einzigen Attention-Operation verwendet der Transformer mehrere „Heads“: Heads erfassen unterschiedliche Beziehungen (z. B. Syntax vs. Semantik). Die Outputs der Heads werden konkateniert und linear projiziert.

Vorteil: Das Modell lernt gleichzeitig diversifizierte Kontextabhängigkeiten.

Cross-Attention ist ein Mechanismus, der es dem Modell ermöglicht, über weitere Entfernung von Tokens auf externe Informationen zu achten wie den Eingabetext (Prompt) oder andere Modelle. Das hat insbesondere auch für den Übergang von der Encoder- zur Decoder-Schicht eine Bedeutung.

Das erreicht das Modell durch die folgenden Schritte:

  • Query-, Key- und Value-Vektoren: Das Modell generiert Query-, Key- und Value-Vektoren aus den Eingabe-Embeddings. Der Query-Vektor repräsentiert den Kontext, der Key-Vektor repräsentiert die Eingabe-Token, und der Value-Vektor repräsentiert die Wichtigkeit jedes Tokens.
  • Achtungsgewichte: Das Modell berechnet Achtungsgewichte, indem es das Skalarprodukt von Query- und Key-Vektoren berechnet. Diese Gewichte repräsentieren die Wichtigkeit jedes Tokens im Kontext.
  • Gewichtete Summe: Das Modell berechnet eine gewichtete Summe der Value-Vektoren, indem es die Achtungsgewichte als Koeffizienten verwendet. Das generiert eine kontextualisierte Darstellung des Eingabetextes.

Nach der grundlegenden Übersicht zu LLMs geht es im nächsten Beitrag um die Hardwareanforderungen und unterschiedliche pretrained Models.


URL dieses Artikels:
https://www.heise.de/-10283768

Links in diesem Artikel:
[1] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-1-10283768.html
[2] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-2-10296098.html
[3] https://www.heise.de/blog/Per-Anhalter-durch-die-KI-Galaxie-LLM-Crashkurs-Teil-3-10296358.html
[4] https://arxiv.org/abs/1706.03762
[5] mailto:rme@ix.de

Copyright © 2025 Heise Medien

Adblock test (Why?)

  • 28. Februar 2025 um 08:33

Künstliche Superintelligenz (ASI) und Allgemeine Künstliche Intelligenz (AGI)

Von Dr. Michael Stal

Vom gewöhnlichen LLM zur menschenähnlichen KI

(Bild: von DALL-E generiert)

Sind große Sprachmodelle tatsächlich kurz vor dem Erreichen eines menschlichen Niveaus, wie in einigen Publikationen und YouTube-Kanälen behauptet?

In derzeitigen Diskussionen über generative Künstliche Intelligenz werden häufig Begriffe wie Künstliche Superintelligenz (ASI – Artificial Super Intelligence) und Allgemeine Künstliche Intelligenz (AGI – Artificial General Intelligence) verwendet. Sie erwecken den Eindruck, dass wir mit den heutigen großen Sprachmodellen (LLMs) kurz vor der Erreichung von ASI oder AGI stehen. Laut IBM ist "künstliche Superintelligenz (ASI) ein hypothetisches, softwarebasiertes künstliches Intelligenzsystem (KI) mit einem intellektuellen Umfang jenseits menschlicher Intelligenz. Auf der grundlegendsten Ebene verfügt diese superintelligente KI über hochmoderne kognitive Funktionen und hochentwickelte Denkfähigkeiten, die fortschrittlicher sind als die eines jeden Menschen."

Motivation: Vision einer menschlichen KI

Ich vertrete jedoch eine andere Perspektive. Obwohl LLMs bedeutende Fortschritte in der Verarbeitung und Generierung natürlicher Sprache gemacht haben, sind sie im Wesentlichen ausgeklügelte statistische Modelle, die im Mustererkennen glänzen. Sie sind durch die begrenzte Menge an qualitativ hochwertigen verfügbaren Trainingsdaten eingeschränkt. Wenn wir die leicht zugänglichen Daten erschöpfen, wird es für Unternehmen wie OpenAI oder Anthropic zunehmend schwieriger, wie in der Vergangenheit erhebliche Fortschritte in Geschwindigkeit und Wissen ihrer Modelle zu erzielen.

Wie würde also eine wirklich menschenähnliche KI aussehen? Eine authentisch intelligente Maschine würde mehrere Schlüsselmerkmale aufweisen:

Proaktivität

Anstatt sich ausschließlich auf große Mengen an vorhandenen Daten zu verlassen, sollte eine KI die Fähigkeit haben, proaktiv neues Wissen und Erfahrungen durch selbstlernende Mechanismen zu suchen. Dies beinhaltet das Initiieren von Interaktionen mit anderen Maschinen und Menschen, um Informationen in Echtzeit zu erwerben. Eine wirklich intelligente Maschine würde nicht passiv statische Daten verarbeiten, sondern aktiv mit ihrer Umgebung interagieren, um ihr Verständnis zu erweitern.

  • Selbstlernende Fähigkeiten: Die KI sollte Algorithmen implementieren, die es ihr ermöglichen, dynamisch aus neuen Daten zu lernen, ohne explizite menschliche Programmierung für jede neue Situation.
  • Interaktives Engagement: Durch das Starten von Gesprächen oder Kollaborationen kann die KI verschiedene Perspektiven und Datenpunkte sammeln und so ihre Wissensbasis bereichern.

Autonomes Verhalten

Autonomie ist essenziell, damit eine KI wirklich ihre Umgebung erkunden und mit ihr interagieren kann. Eine intelligente Maschine sollte in der Lage sein, unabhängige Entscheidungen über ihre Handlungen und zukünftigen Richtungen zu treffen, ohne ständige menschliche Führung. Diese Autonomie ermöglicht es der KI, sich in komplexen, dynamischen Umgebungen zurechtzufinden und sich an neue Situationen und Herausforderungen anzupassen, wenn diese auftreten.

  • Entscheidungsfähigkeiten: Implementierung fortschrittlicher Algorithmen, die es der KI ermöglichen, Optionen abzuwägen und Entscheidungen basierend auf Zielen und gelernten Erfahrungen zu treffen.
  • Anpassungsfähigkeit an die Umwelt: Die KI sollte ihre Strategien als Reaktion auf Veränderungen anpassen, ähnlich wie Menschen es tun, wenn sie mit neuen Umständen konfrontiert werden.

Emotionale Intelligenz

Während Emotionen bei Menschen komplex und nicht vollständig verstanden sind, könnte die Einbeziehung von Elementen, die Emotionen wie Neugier und Zufriedenheit analog sind, die Fähigkeit einer KI verbessern, zu erkunden und zu lernen. Neugier treibt die Suche nach neuem Wissen an und veranlasst die KI, neuartige oder "interessante" Themen zu untersuchen.

  • Verstärkendes Lernen: Nutzung von Frameworks für verstärkendes Lernen kann emotionale Treiber simulieren, indem bestimmte Verhaltensweisen belohnt werden und die KI ermutigt wird, sie zu wiederholen.
  • Menschliche Interaktion: Damit eine KI effektiv mit Menschen interagieren kann, muss sie emotionale Hinweise verstehen und darauf reagieren können, was natürlicheres und bedeutungsvolleres Engagement ermöglicht.
  • Empathie und Verständnis: Entwicklung von Algorithmen, die es der KI ermöglichen, menschliche Emotionen zu erkennen und angemessen darauf zu reagieren, kann Zusammenarbeit und Vertrauen verbessern.

Sensoren und Aktoren

Die physische Interaktion mit der Umwelt ist entscheidend, damit eine KI erfahrungsbasiertes Wissen erlangen kann. Ausgestattet mit Sensoren und Aktoren kann eine KI ihre Umgebung wahrnehmen und Aktionen ausführen, die die Welt beeinflussen. Diese Verkörperung ermöglicht es der KI, aus direkter Erfahrung zu lernen und Informationen zu erwerben, die in bereits vorliegenden Datensätzen nicht vorhanden sind.

  • Verkörperte KI: Ob in einen Roboterkörper integriert oder mit entfernten Sensoren verbunden, erhält die KI eine physische Präsenz, die ihre Lernfähigkeiten verbessert.
  • Interaktion in der realen Welt: Durch Manipulation und Beobachtung kann die KI Hypothesen testen und die kausalen Beziehungen erlernen, die die physische Welt regieren.
  • Multimodales Lernen: Die Kombination von visuellen, auditiven, taktilen und anderen sensorischen Eingaben kann zu einem ganzheitlicheren Verständnis komplexer Umgebungen führen.

Denken, Meta-Denken und Reflexion

Fortgeschrittene kognitive Prozesse wie Denken und Selbstreflexion sind unerlässlich, damit eine KI aus ihren Erfahrungen, einschließlich Misserfolgen, lernen kann. Durch die Analyse vergangener Handlungen und Ergebnisse kann die KI ihr Verhalten anpassen, um die zukünftige Leistung zu verbessern.

  • Metakognitive Fähigkeiten: Die KI sollte in der Lage sein, über ihre eigenen Denkprozesse nachzudenken, was es ihr ermöglicht, ihre Lernstrategien zu optimieren.
  • Fehleranalyse: Die Identifizierung und das Verständnis von Fehlern ermöglichen es der KI, ihre Algorithmen zu verfeinern und Fehler nicht zu wiederholen.
  • Bewusstsein und Selbstwahrnehmung: Obwohl umstritten und herausfordernd, könnte die Entwicklung eines gewissen Grades an Selbstwahrnehmung der Schlüssel zur Erreichung echter AGI sein, indem die KI ihre eigenen Ziele setzen und ihre Existenz in einem breiteren Kontext verstehen kann.

Herausforderungen und der Weg in die Zukunft

Während aktuelle KI-Technologien beeindruckende Fortschritte gemacht haben, erfordert die Erreichung echter AGI oder ASI die Überwindung signifikanter Hürden:

  • Datenbeschränkungen: Da wir die Grenzen der verfügbaren Daten erreichen, werden neue Methoden der Wissensakquisition essenziell.
  • Ethische Überlegungen: Die Entwicklung von KI mit Autonomie und emotionalem Verständnis wirft wichtige ethische Fragen zu Kontrolle, Rechten und Sicherheit auf.
  • Technische Komplexität: Die Implementierung fortgeschrittener Denkprozesse und Selbstreflexion erfordert Durchbrüche in Rechenmodellen und Verarbeitungskapazitäten.
Fazit

Die Reise hin zu menschenähnlicher KI besteht nicht nur darin, Modelle zu skalieren oder Daten zu erhöhen, sondern erfordert ein grundlegendes Umdenken, wie KI-Systeme lernen, interagieren und denken. Indem wir uns auf Proaktivität, Autonomie, emotionale Intelligenz, physische Verkörperung und fortgeschrittene kognitive Prozesse konzentrieren, können wir der Entwicklung von KI näher kommen, die nicht nur menschliche Fähigkeiten nachahmt, sondern auch auf wirklich intelligente und autonome Weise mit der Welt interagiert.

Nur indem wir diese facettenreichen Herausforderungen angehen, können wir hoffen, das volle Potenzial der Künstlichen Intelligenz zu realisieren und den Weg für Maschinen zu ebnen, die wirklich denken, lernen und vielleicht eines Tages ein Bewusstsein ähnlich dem unseren besitzen.


URL dieses Artikels:
https://www.heise.de/-10039060

Links in diesem Artikel:
[1] mailto:map@ix.de

Copyright © 2024 Heise Medien

Adblock test (Why?)

  • 20. November 2024 um 12:15

Technical Debt Records – Dokumentation technischer Schulden

Von Dr. Michael Stal
Dokumente umgeben Mann am PC

(Bild: Generated by OpenAI DALL E)

Um technische Schulden systematisch zu dokumentieren und zu verwalten, eignen sich Technical Debt Records (TDRs).

Zur Abwechslung geht es diesmal weder um Microcontroller noch um KI, sondern um Softwarearchitektur, genauer gesagt um technische Schulden und ihre Dokumentation. In der heutigen schnelllebigen Softwareentwicklung stehen Teams vor der Herausforderung, kontinuierlich neue Funktionen bereitzustellen und gleichzeitig die Codequalität zu erhalten. Dabei entstehen oft Kompromisse, die wir als Technical Debt (Technische Schulden) bezeichnen. Um diese systematisch zu dokumentieren und zu verwalten, lassen sich Technical Debt Records (TDRs) nutzen. Dieser Artikel erläutert die Bedeutung von TDRs und stellt ein Werkzeug vor, das die Erstellung von TDRs vereinfacht.

Was sind Technical Debt Records (TDRs)?

Softwarearchitektinnen und -architekten nutzen heutzutage ADRs (Architecture Design Records), wenn sie Architekturentscheidungen festhalten wollen. ADRs haben sich in einer Vielzahl von Projekten als Micro-Architekturdokumente etabliert. Sie unterliegen der Versionskontrolle und liegen damit in der Codebasis. Was für Architekturentscheidungen gilt, lässt sich auch für technische Schulden nutzen.

Ein Technical Debt Record (TDR) ist ein strukturiertes Dokument, das Details über technische Schulden in einem Softwareprojekt festhält. Technische Schulden entstehen, wenn Entwicklerinnen und Entwickler kurzfristige Lösungen wählen, die sich zwar schnell implementieren lassen, aber langfristig zu erhöhtem Wartungsaufwand, schlechterer Performance oder anderen Nachteilen führen. TDRs bieten eine klare Übersicht über bestehende technische Schulden, deren Auswirkungen und die Maßnahmen zu ihrer Behebung.

Motivation für TDRs

Technische Schulden können, wenn sie unkontrolliert bleiben, erhebliche negative Auswirkungen auf ein Projekt haben:

  • Codequalität: Erhöhter Wartungsaufwand und sinkende Codequalität.
  • Skalierbarkeit: Schwierigkeiten bei der Erweiterung und Anpassung der Software.
  • Performance: Mögliche Leistungseinbußen durch suboptimale Implementierungen.
  • Risikomanagement: Erhöhtes Risiko von Systemausfällen oder Sicherheitslücken.

Durch die systematische Dokumentation mittels TDRs können Teams diese Schulden frühzeitig erkennen, priorisieren und gezielt angehen, bevor sie unkontrollierbar werden.

Vorteile von TDRs für Entwicklerinnen, Architekten und Tester

Es ist somit essenziell, technische Schulden zu dokumentieren. Technical Debt Records bieten hierbei verschiedene Vorteile für die Projektbeteiligten.

Für Entwickler:

  • Transparenz: Klare Dokumentation der bestehenden technischen Schulden erleichtert das Verständnis der Codebasis.
  • Priorisierung: Ermöglicht die Fokussierung auf kritische Bereiche, die sofortige Aufmerksamkeit erfordern.
  • Wiederverwendbarkeit: Vermeidung von doppeltem Aufwand durch das Bewusstsein über bereits bekannte Probleme.

Für Architekten:

  • Strategische Planung: Unterstützung bei der Planung von Refactoring-Maßnahmen und Architekturverbesserungen.
  • Risikobewertung: Einschätzung der Auswirkungen technischer Schulden auf die Gesamtarchitektur.
  • Entscheidungsgrundlage: Datenbasierte Entscheidungen zur Weiterentwicklung der Systemarchitektur.

Für Tester:

  • Fokus auf kritische Bereiche: Kenntnis über problematische Bereiche ermöglicht gezieltere Tests und höhere Testabdeckung.
  • Verbesserte Teststrategien: Anpassung der Testpläne basierend auf den identifizierten technischen Schulden.
  • Qualitätssicherung: Sicherstellung, dass behobene Schulden die gewünschte Qualitätssteigerung bringen.

Damit die Beschreibung von Technical Debt Records nicht nur theoretisch bleibt, soll das konkrete Beispiel im folgenden Kasten zur Veranschaulichung dienen. Es geht um eine veraltete Authentifizierungsbibliothek. Hat das zugehörige TDR schon ein paar Stufen des Workflows durchlaufen, könnte es sich so präsentieren.

Das TDR-Template und seine Felder

Ein gut strukturiertes TDR-Template ist entscheidend für die effektive Dokumentation technischer Schulden. Ein Werkzeug (siehe weiter unten) generiert TDRs mit folgenden Feldern:

  • Titel: Eine prägnante Bezeichnung der technischen Schuld.
  • Autor: Die Person, die die Schuld identifiziert oder dokumentiert hat.
  • Version: Die Version des Projekts oder der Komponente, in der die Schuld existiert.
  • Datum: Das Datum der Identifikation oder Dokumentation der technischen Schuld.
  • State: Der aktuelle Status der technischen Schuld (z.B. Identified, Analyzed, Approved, In Progress, Resolved, Closed, Rejected).
  • Relations: Verweise auf andere verwandte ADRs oder TDRs, um Zusammenhänge zu verdeutlichen.
  • Zusammenfassung: Eine kurze Übersicht über die technische Schuld und deren Bedeutung.
  • Kontext: Detaillierte Hintergrundinformationen, warum die Schuld entstanden ist (z.B. Zeitdruck, veraltete Technologien).
  • Auswirkungen:
    • Technische Auswirkungen: Wie die Schuld die Systemleistung, Skalierbarkeit oder Wartbarkeit beeinflusst.
    • Geschäftliche Auswirkungen: Die Auswirkungen auf Geschäftsprozesse, Kundenzufriedenheit oder Risikoebenen.
  • Symptome: Beobachtbare Anzeichen, die auf die Präsenz der technischen Schuld hinweisen (z.B. häufige Bugs, langsame Performance).
  • Schweregrad: Die Kritikalität der Schuld (Critical, High, Medium, Low).
  • Potenzielle Risiken: Mögliche negative Folgen, wenn die Schuld nicht behoben wird (z.B. Sicherheitslücken, erhöhte Kosten).
  • Vorgeschlagene Lösung: Empfohlene Maßnahmen zur Behebung der technischen Schuld.
  • Kosten der Verzögerung: Die Konsequenzen, wenn die Behebung der Schuld verzögert wird.
  • Aufwand zur Behebung: Geschätzter Aufwand in Zeit und Ressourcen, um die Schuld zu beheben.
  • Abhängigkeiten: Andere Aufgaben, Komponenten oder externe Faktoren, die die Behebung der Schuld beeinflussen.
  • Zusätzliche Hinweise: Weitere relevante Informationen oder Überlegungen zur Schuld.

Das sind auf den ersten Blick sehr viele Aspekte. Doch keine Sorge, die Dokumentation dieser Felder erfolgt inkrementell im Lebenszyklus der dokumentierten technischen Schuld. Den augenblicklichen Zustand und damit den Workflow eines TDR beschreibt das Feld state.

Rationale für das State-Feld

Das State-Feld spiegelt den Workflow wider, also wie Entwickler technische Schulden handhaben sollten. Es hilft dabei, den Fortschritt bei der Bearbeitung der Schuld zu verfolgen und sicherzustellen, dass keine Schulden unbeachtet bleiben. Die definierten Zustände sind:

  • Identified: Die technische Schuld wurde erkannt.
  • Analyzed: Die Auswirkungen und der Aufwand zur Behebung wurden bewertet.
  • Approved: Die Behebung der Schuld wurde genehmigt.
  • In Progress: Die Arbeit zur Behebung der Schuld ist im Gange.
  • Resolved: Die technische Schuld wurde behoben.
  • Closed: Der TDR wurde abgeschlossen und ist nicht mehr relevant.
  • Rejected: Die Behebung der Schuld wurde abgelehnt.

Diese Zustände ermöglichen es Teams, den Status jeder technischen Schuld klar zu definieren und entsprechende Maßnahmen zu ergreifen.

Inkrementelle Anpassung der Felder je nach State

Beim ersten Identifizieren einer technischen Schuld können einige Felder noch leer bleiben:

  • Initiale Identifikation (Identified):
    • Zu beschreiben: Titel, Autor, Version, Datum, State, Zusammenfassung, Kontext.
    • Leer: Auswirkungen, Symptome, Schweregrad, Potenzielle Risiken, Vorgeschlagene Lösung, Kosten der Verzögerung, Aufwand zur Behebung, Abhängigkeiten, Zusätzliche Hinweise.
  • Analysephase (Analyzed):
    • Zu beschreiben: Alle Felder des Identified-Status plus Auswirkungen, Symptome, Schweregrad, Potenzielle Risiken.
  • Genehmigungsphase (Approved):
    • Zu beschreiben: Alle bisherigen Felder plus Vorgeschlagene Lösung, Kosten der Verzögerung.
  • Umsetzungsphase (In Progress):
    • Zu beschreiben: Alle bisherigen Felder plus Aufwand zur Behebung, Abhängigkeiten.
  • Abschlussphase (Resolved & Closed):
    • Zu beschreiben: Alle Felder einschließlich Zusätzliche Hinweise.

Durch diese schrittweise Ergänzung bleibt die Dokumentation stets aktuell und reflektiert den Fortschritt bei der Behebung der technischen Schulden.

Ein Werkzeug zur Erstellung von TDRs

Die Dokumentation technischer Schulden würde dann an Akzeptanz verlieren, wenn die Dokumentation technischer Schulden sich als manuell und aufwendig erweist. In diesem Fall könnte es auch passieren, dass Entwickler Felder vergessen, umbenennen oder wichtige Felder ignorieren.

Der TDR-Generator ist ein Go-basiertes Werkzeug, das die Erstellung von Technical Debt Records in verschiedenen Formaten automatisiert. Es unterstützt Markdown, Plain ASCII, PDF und Excel und erleichtert somit die Integration in unterschiedliche Entwicklungs- und Dokumentationsprozesse.

Features des TDR-Generators

Werkzeugunterstützung für TDRs hat sich auch schon bei ADRs bewährt. So lassen sich Schablonen generieren, mit deren Hilfe Architektinnen und Architekten die technischen Schulden beschreiben. Dementsprechend weist der TDR-Generator folgende Vorteile auf:

  • Benutzerfreundlich: Interaktive Eingabeaufforderungen führen Benutzer durch das Ausfüllen der TDR-Felder.
  • Flexibel: Unterstützung mehrerer Ausgabeformate zur Anpassung an verschiedene Anforderungen.
  • Automatische Validierung: Überprüfung der Eingaben auf Vollständigkeit und Korrektheit.
  • Version Control Integration: Leichtes Einchecken der generierten TDRs in Systeme wie Git oder SVN.

Repository und Installation

Der TDR-Generator ist auf GitHub verfügbar. Sie können das Repository hier [1] finden.

Zur Installation bedarf es folgender Schritte:

  1. Klonen des Repositories: git clone git@github.com/ms1963/TechnicalDebtRecords.git
  2. Initialisieren des Go-Moduls: go mod init technical_debt_generator
  3. Installieren der Abhängigkeiten: go get github.com/phpdave11/gofpdf && go get github.com/xuri/excelize/v2
  4. Kompilieren des Programmes: go build generate-td.go

Wer möchte, kann aber auch einfach make im Quellcodeverzeichnis aufrufen. Dadurch erfolgt die Kompilation automatisch über das mitgelieferte Makefile. Voraussetzung ist allerdings in jedem Fall die vorhergehende Installation des go-Compilers [2].

Nutzung des TDR-Generators

Das Programm lässt sich über die Kommandozeile mit verschiedenen Optionen ausführen.

Verfügbare Optionen:

  • -format: Gibt das Ausgabeformat an. Mögliche Werte sind markdown, ascii, pdf, excel. Standard ist markdown.
  • -output: (Optional) Gibt den Dateinamen für die Ausgabe an. Wenn nicht angegeben, wird ein Standardname verwendet.
  • -empty: (Optional) Erstellt ein leeres TDR mit Platzhaltern, ohne nach Eingaben zu fragen.
  • --help oder -h: Zeigt die Hilfsnachricht mit Nutzungshinweisen an.

Beispiele:

  1. Generiere ein Markdown-Dokument: ./generate-td -format markdown
  2. Generiere ein PDF-Dokument mit benutzerdefiniertem Dateinamen: ./generate-td -format pdf -output mein_td_record.pdf
  3. Generiere ein leeres Excel-Dokument: ./generate-td -format excel -empty
  4. Zeige eine Hilfemeldung an: ./generate-td --help

Integration in Versionskontrollsysteme

Um die Nachverfolgung und Zusammenarbeit zu erleichtern, sollten TDRs in ein Versionskontrollsystem wie Git oder SVN eingecheckt werden. Dies ermöglicht:

  • Versionierung: Nachverfolgung von Änderungen und Historie der technischen Schulden.
  • Zusammenarbeit: Gemeinsame Bearbeitung und Überprüfung von TDRs durch das Team.
  • Zugänglichkeit: Einfache Integration in bestehende Entwicklungsprozesse und Pipelines.

Beispiel für Git:

  1. Füge das TDR dem Repository hinzu: git add technical_debt_record.md
  2. Bestätige die Änderung: git commit -m "Add TDR für veraltete Authentifizierungsbibliothek"
  3. Speichere die Änderung: git push origin main

Durch die Einbindung von TDRs in das Versionskontrollsystem bleibt die Dokumentation stets aktuell und für alle Teammitglieder zugänglich.

Fazit

Technical Debt Records (TDRs) sind ein effektives Instrument zur Verwaltung technischer Schulden in Softwareprojekten. Sie bieten Transparenz, erleichtern die Priorisierung und unterstützen strategische Entscheidungen zur Verbesserung der Codequalität und Systemarchitektur. Der vorgestellte TDR-Generator vereinfacht die Erstellung dieser wichtigen Dokumente und integriert sich nahtlos in bestehende Entwicklungs- und Versionskontrollprozesse.

Indem Teams TDRs konsequent verwenden und in ihre Workflows integrieren, können sie die negativen Auswirkungen technischer Schulden minimieren und die langfristige Gesundheit und Wartbarkeit ihrer Softwareprojekte sicherstellen.

Wie erwähnt, finden Sie das beschriebene Werkzeug in einem GitHub-Repository [3].


URL dieses Artikels:
https://www.heise.de/-9876115

Links in diesem Artikel:
[1] https://github.com/ms1963/TechnicalDebtRecords/
[2] https://go.dev/doc/install
[3] https://github.com/ms1963/TechnicalDebtRecords/
[4] mailto:who@heise.de

Copyright © 2024 Heise Medien

Adblock test (Why?)

  • 26. September 2024 um 09:05

CrowView Note – ein "Notebook" nicht nur für SBC-Entwickler

Von Dr. Michael Stal
Das CrowView Note - Notebook für SBCs

Ein Raspberry Pi 4 ist über ein Adapterboard mit dem CrowView Note verbunden. Auf dem Bildschirm ist Raspberry Pi OS zu sehen.

(Bild: Elecrow, Screenshot und Bearbeitung: heise online)

Es schaut aus wie ein Notebook, besitzt aber keine CPU. Das CrowView Note benutzt stattdessen SBCs wie Raspberry Pi, Nvidia Jetson Nano als Schaltzentrale.

Wer den Tastatur-PC Raspberry Pi 400 [1] erworben hat, muss selbst für einen Bildschirm und eine Maus sorgen. Das Produkt bietet eine Tastatur mit integriertem Raspberry Pi 4 und Anschlussmöglichkeiten für eine Maus und einen Bildschirm. Sollte bald ein Raspberry Pi 500 erscheinen, dürfte es sich bezüglich seiner Spezifikation ähnlich wie der Vorgänger präsentieren.

Elecrow erweitert das Konzept des Raspberry Pi 400 um einen Bildschirm und ein Trackpad. Das Produkt CrowView Note kommt als Notebook mit Bildschirm und Tastatur inklusive Touchpad, aber ohne eigenen Prozessor daher. Zu diesem Zweck dient stattdessen ein über eine Brücke anschließbarer Raspberry Pi oder Nvidia Jetson Nano. Die Aufgaben des Mainboards übernehmen also SBCs (Single Board Computers). Man kann auch ältere Raspberry Pis anschließen, etwa über Kabel. Ob sich weitere SBCs mit dem Notebook vertragen, habe ich nicht getestet. Die Chance dafür dürfte hoch sein. Escrow gibt jedenfalls an, folgende Hardware zu unterstützen:

  • Raspberry Pi 5, 4B, 3B, 3B+, Zero
  • Rock Pi
  • Beaglebone
  • LattePanda V1
  • Nvidia Jetson Nano
  • Orange Pi 4B
  • Banana Pi M5

Aktuell läuft eine Kickstarter-Kampagne zum CrowView Note [2], später kommt das Gerät in den regulären Handel.

CrowView Note mit verschiedenen SBCs

CrowView Note mit allerlei Einplatinencomputern.

(Bild: Elcrow)

Über eine Brücke musst du gehen

Möglicherweise bringt der Hersteller auch noch weitere Bridges (kleine Boards zum Anschluss von SBCs) auf den Markt, sollten viele Kunden das wünschen. Die Bridges beziehungsweise Adapterboards für Raspberry Pi werden in die linke Seite und in die Frontseite des CrowView Note eingesteckt und erlauben den bequemen Anschluss des jeweiligen SBC ganz ohne Kabel. Möglich ist auch die Verbindung eines Smartphones oder Tablets mit dem CrowView Note. Darüber hinaus kann das Gerät als externer 14-Zoll-Monitor für Geräte jeder Art über ein Mini-HDMI-Kabel oder USB-C-Kabel fungieren. Wer die Bridge – zwei kleine Boards – für den Raspberry Pi 4 oder 5 mit einem Gehäuse einsetzen möchte, muss darauf achten, dass das Gehäuse Zugriff auf die vorderen und linken Anschlüsse gewährleistet. Sollte dies nicht der Fall sein, kann man eins der vielen Gehäusemodelle für 3D-Drucker entsprechend modifizieren. Die Bridges sind übrigens nicht im Lieferumfang enthalten, sondern separat erhältlich. Pro Board beziehungsweise Brücke verlangt der Hersteller einen Obolus von 5 Euro.

Zusätzlich lässt sich das Quasi-Notebook mit diversen Spielekonsolen kombinieren.

Natürlich ist das CrowView Note nicht die einzige Alternative, um mit SBCs zu arbeiten.

  • Alternativ lässt sich auch remote auf Boards zugreifen (zum Beispiel über ssh), um so mit Host/Target-Entwicklung zu arbeiten, aber dadurch sinkt in der Regel die Produktivität.
  • Andererseits könnten Nutzer KVM-Switches einsetzen, damit mehrere SBCs und Computer sich Bildschirm, Tastatur und Maus teilen, was sich aber eher für stationäre Installationen eignet. Zusätzlich gewünschte Mobilität erfordert in diesem Fall das Mitnehmen von externem Bildschirm, Tastatur und Maus.
  • Der SBC lässt sich auch zum Standalone-Computer aufrüsten. Das kostet allerdings Geld und Platz.

Da das hier vorgestellte Notebook, wie erwähnt, Bildschirm, Tastatur und Trackpad bereits mitbringt, dürfte diese Variante jedoch die bequemste sein – speziell, wenn Mobilität gewünscht ist.

Spezifikation

Das getestete CrowView Note verfügt über einen 14-Zoll-Monitor mit IPS-Panel und Full-HD-Auflösung (1920 × 1080 Pixel). Als abgedeckten Farbraum gibt der Hersteller 100 % sRGB an; als maximale Helligkeit 300 cd/m². Die Bildwiederholrate beträgt 60 Hz, mit Support für variable Refreshraten (VRR). Auf der linken Seite lassen sich die oben erwähnten Bridges für SBCs anschließen, alternativ auch über Kabel oder Adapter. Auf der rechten Seite stehen ein Anschluss für das Netzteil, ein Kopfhörerausgang sowie eine USB-C- und eine USB-A-Schnittstelle zur Verfügung. Eine USB-Schnittstelle unterstützt Power Delivery (PD) für das Aufladen externer Geräte mit 5V/5A. Zudem liefert Elecrow ein 12V/4A-Netzteil mit. Stereo-Lautsprecher sind ebenso wie ein Mikrofon im CrowView Note integriert.

Es existieren also zusammengefasst folgende Schnittstellen:

Links:

  • USB 2.0 Typ A
  • USB Typ C (nur Stromversorgung, keine Datenverbindung)
  • Mini-HDMI-Anschluss

Rechts:

  • USB 2.0 Typ A
  • USB Typ C (Displayport-Alt-Modus, Stromversorgung)
  • Kopfhörereingang
  • Netzsteckereingang 3,5 mm, Gleichstrom/DC

Ein eingebauter Akku bietet 5000 mAh Ladekapazität. Ohne eingeschalteten Bildschirm benötigt das Gerät rund zwei Watt, ansonsten acht Watt Leistung. Die Arbeitszeit hängt natürlich vom Leistungsbedarf des verwendeten SBC ab; bei einem Raspberry Pi 5 sind es bis zu drei Stunden. Wer das Gerät lediglich als externen Monitor nutzt, dürfte mit einer Batterieladung bei einer Laufzeit um 5 Stunden landen. Als positiv empfand ich das geringe Gewicht (1147 g) und die angenehme Größe des CrowView (33,4 cm × 22,2 cm × 1,75 cm), womit man es leicht transportieren kann. Das CrowView Note lässt sich bis zu 180 Grad aufklappen.

Dass das CrowView Note überwiegend aus Kunststoff gefertigt ist, wirkt sich auf die Qualität des Gehäuses nur marginal aus. Es macht einen recht robusten Eindruck. Anders ausgedrückt: Es tut, was es soll.

Anschluss eines Raspberry Pi 5

Der Raspberry Pi 5 lässt sich über Bridges an das CrowView Note anschließen

(Bild: Elecrow)

Neben den offensichtlichen Einsatzgebieten wie Office, Gaming und Entertainment bietet sich auch der Einsatz für Programmierung an, nicht nur für Embedded-Software. Wer Audio hören und seine Umwelt beschallen möchte, kann dies über die zwei eingebauten Stereo-Lautsprecher tun. Natürlich lässt sich davon kein Klang erwarten, der einem hochpreisigen Hi-Fi-System Konkurrenz machen kann. Speziell die schwachen Bässe fallen auf. Als externes Display lässt sich das Produkt genauso nutzen wie als Standalone-Gerät für SBCs.

Bedienung

Der Bildschirm ist matt und lässt sich gut zum Arbeiten verwenden. Bei sehr hellem Tageslicht kommt er zwar an seine Grenzen, leichtet aber im Regelfall ausreichend hell. Die Tastatur ist aus meiner subjektiven Perspektive gut bedienbar. Zum Anschluss von Endgeräten oder SBCs an das Notebook kann man Mini-HDMI oder einen USB-C-Eingang nutzen.

Das Trackpad des Review-Modells ließ wegen fehlenden Druckpunkts kein Drag-and-Drop oder das Scrollen von Bildschirminhalten zu. Laut Aussage des Herstellers sei dies lediglich ein Problem des Vorserien-Prototyps, das bei den ausgelieferten Geräten nicht mehr auftreten soll.

Ein kleiner Hinweis in Sachen Tastatur: Auf dem getesteten Vorserien-Testgerät befindet sich eine US-Tastatur. Die hilfsbereite Mitarbeiterin Annie Xie von Escrow hat während des Tests mitgeteilt, dass Elcrow das Gerät künftig auch mit deutscher Tastatur ausliefern will.

Wer auf das OSD (On-Screen-Display) zugreifen will, um Display-Einstellungen anzupassen, kann dies über Funktionstasten bewerkstelligen. Eine dieser Funktionstasten erlaubt das Umschalten zwischen verschiedenen Geräten. Das ist zum Beispiel wichtig, wenn ein SBC über Mini-HDMI angeschlossen ist und ein weiteres externes Gerät wie ein Smartphone über USB-C/DP (DisplayPort). Insofern verhält sich das CrowView Note wie ein KVM-Switch.

Softwareentwicklung mit und für SBCs

Entwickler von Embedded-Software oder auch anderer Anwendungen für SBCs wie dem Raspberry Pi profitieren vom CrowView Note. Das ist nicht nur dessen Mobilität geschuldet, sondern auch der Tatsache, dass dieses Gerät es auf bequeme Art ermöglicht, diverse SBCs anzuschließen und damit zu experimentieren. Beim Entwickeln, Testen und Debuggen erweist es sich als Vorteil, direkt mit Entwicklungs- und Testwerkzeugen über grafische Bedienoberflächen auf dem SBC arbeiten zu können, zum Beispiel mit Visual Studio Code und den Add-ons PlatformIO oder TinyGo.

Für das mobile Arbeiten mit dem CrowView Note dient einfach ein Smartphone, Tablet oder anderes mobiles Gerät als WLAN-Access-Point für den Netzwerkzugriff. Wer den Raspberry Pi 400 zu schätzen gelernt hat, dürfte sich leicht mit dem CrowView Note anfreunden, zumal dieser zusätzlich Bildschirm und Trackpad mitbringt. Bis auf den SBC und die Bridge bedarf es keinerlei weiterer Hardware. Insgesamt lassen sich alle benötigten Gerätschaften leicht verstauen und transportieren.

Fazit

Das Produkt CrowView Note ist ein sehr preisgünstiges Gerät, das SBC-Nutzern mit Mobilitätsanforderungen eine geeignete Lösung verschafft, sich aber auch gut für den stationären Betrieb eignet. Die Idee, ein Notebookgehäuse inklusive Tastatur, Monitor und Maus mit einem SBC zu kombinieren, ist innovativ und bietet einige Vorteile, die das CrowView Note gut ausspielen kann. Der anvisierte Verkaufspreis von etwa 169 Euro ist auf jeden Fall gerechtfertigt.

Wer das Gerät erwerben möchte, kann dafür die noch laufende Kickstarter-Kampagne [3] nutzen. Der Preis beträgt 118 Euro (Early Bird) beziehungsweise 127 Euro (KickStarter-Preis). Nach Ende der Kampagne schlägt das Produkt mit rund 40 Euro mehr zu Buche (169 USD / Euro).


URL dieses Artikels:
https://www.heise.de/-9861699

Links in diesem Artikel:
[1] https://www.heise.de/tests/Raspberry-Pi-400-im-Test-Kleiner-Computer-fuer-Einsteiger-und-Bastler-4967904.html
[2] https://www.kickstarter.com/projects/elecrow/crowview-note-empowering-your-device-as-a-laptop/description
[3] https://www.kickstarter.com/projects/elecrow/crowview-note-empowering-your-device-as-a-laptop?lang=de
[4] mailto:rme@ix.de

Copyright © 2024 Heise Medien

Adblock test (Why?)

  • 13. September 2024 um 17:00

Indiegogo, Kickstarter & Co – Die dunkle Seite des Crowdfunding

Von Dr. Michael Stal

(Bild: (c) Flickr)

Wer in Crowdfunding-Projekte investiert, muss sich den Risiken bewusst sein. Die Plattformen weisen meist jede Verantwortung von sich.

Crowdfunding hilft beim Anstoßen von Projekten, indem zahlreiche Unterstützer in ein Projekt investieren, an das sie glauben. Der Erfolg ist aber nicht garantiert, und es gilt auf Betrugsmaschen zu achten, zumal die Crowdfunding-Plattformen das Risiko auf die Investoren abwälzen.

Motivation

Ich möchte mit einer Erfolgsgeschichte beginnen:

Bambu Lab war völlig unbekannt, als das aufstrebende 3D-Drucker-Unternehmen seine X1/X1C-Kampagne über Kickstarter startete. Es sammelte schließlich fast 55 Millionen HK-$ von 5575 Unterstützern. In den folgenden Monaten stellte Bambu Lab die X1/X1C-Produktlinie fertig und schickte alle Perks an die Unterstützer. Dieser neue CoreXY 3D-Drucker erwies sich als revolutionäres, preisgekröntes und äußerst erfolgreiches Produkt, dem bald weitere Produkte wie der P1P und der P1S folgten. Es erübrigt sich zu sagen, dass Bambu Lab eine riesige Erfolgsgeschichte mit einem glücklichen Ende für das Crowdfunding-Unternehmen, den Kampagneninhaber und die Unterstützer war.

Einer der Vorteile von Crowdfunding lässt sich wie folgt zusammenfassen: Crowdfunding-Plattformen bringen innovative Kampagnenmacher und begeisterte Unterstützer zusammen. Sie ermöglichen es Start-ups und etablierten Unternehmen, Finanzmittel für innovative Produkte zu erhalten.

Im Nachhinein betrachtet, funktionieren nicht alle Kampagnen so gut. In einigen Fällen liefern die Werber kein Produkt, stellen nur ein unterdurchschnittliches Produkt her, haben kein Geld mehr oder entpuppen sich als Betrüger. Jahr für Jahr gehen auf diese Weise Millionen von US-Dollar verloren. Es ist nie vorhersehbar, ob ein Projekt erfolgreich sein wird, wie es bei Joint Ventures ebenfalls der Fall ist. Gründe für das Scheitern können die Undurchführbarkeit der Innovation, Budgetüberschreitungen, enorme Projektverzögerungen durch unglückliche Umstände wie Covid-19, zu niedrig angesetzte Kosten oder drastische Preiserhöhungen für notwendige Komponenten sein.

Lehren

Das Scheitern von Projekten lässt sich zwar nie vermeiden, aber Betrug schon.

Ein chinesischer Kampagnenbetreiber sammelte mit seiner Indiegogo-Kampagne für den kleinsten Mini-PC der Welt über eine Million US-Dollar ein, schaffte aber keine der versprochenen Perks. Nach einiger Zeit gab es sogar keine Kommunikation mehr zwischen den Unterstützern und dem Kampagnenbesitzer. Es schien, als sei der Eigentümer einfach von der Bildfläche verschwunden. Als die Unterstützer Indiegogo um Hilfe baten, fühlte sich das Crowdfunding-Unternehmen nicht zuständig. Sie sperrte einfach alle weiteren Beiträge, versah die Projektwebsite mit dem Hinweis "Diese Kampagne wird derzeit untersucht", lieferte aber weder die Ergebnisse der sogenannten Untersuchung noch eine Rückerstattung an die betrogenen Kunden.

Lektion 1: Crowdfunding-Unternehmen kümmern sich nicht (allzu sehr) um die Unterstützer. Sie verdienen Geld, indem sie eine Plattform für verschiedene Parteien bereitstellen, und behandeln die Geldgeber wie Risikokapitalgeber, die alle Risiken selbst tragen sollen.

Indiegogo und Kickstarter agieren im Grunde wie Wettbüros für Pferderennen, bei denen fast keine Transparenz über die Pferdebesitzer (auch Kampagnenbesitzer genannt) herrscht. Jeder Teilnehmer an solchen Szenarien trägt hohe Risiken, wobei das Wettbüro die einzige Ausnahme ist. Offensichtlich sind die Regeln zwischen den Kunden und der Crowdfunding-Plattform so definiert, dass die Bank (oder das Wettbüro) immer gewinnt.

Lektion 2: Wer sich an einer Crowdfunding-Kampagne beteiligen möchte, sollte mit einem Scheitern des Projekts und dem vollständigen Verlust der Beiträge leben können.

Jeder Unterstützer sollte sich dieser Realität bewusst sein. Er/sie könnte seinen/ihren gesamten Beitrag verlieren oder ein überbezahltes oder sogar nutzloses Produkt erhalten. Sicher, die Mehrheit der Kampagnen ist letztlich erfolgreich. Es gibt jedoch auch eine beträchtliche Anzahl von Kampagnen, die scheitern. Ich mache mir keine Sorgen um das Scheitern von Projekten trotz der enormen Anstrengungen der Kampagnenbetreiber. Das ist ein bekanntes und akzeptables Risiko, das die Geldgeber im Hinterkopf behalten sollten, wenn sie einen Beitrag leisten. Aber ich mache mir Sorgen um betrügerische Kampagnen, bei denen die Betreiber einfach die gesammelten Beiträge nehmen und verschwinden.

Lektion 3: Wer dringend ein bestimmtes Produkt benötigt, sollte sich nicht an einer Crowdfunding-Kampagne beteiligen, sondern es stattdessen bei etablierten Quellen kaufen.

Lektion 4: Derzeit gibt es keine Sicherheitsnetze für Unterstützer. Auch gibt es keine Transparenz oder Rechenschaftspflicht gegenüber den Kampagnenbetreibern. Eine Kampagne gleicht einem Spiel oder einer Wette auf die Zukunft, ohne ausreichende Transparenz in Bezug auf die Eigentümer der Kampagne.

Lektion 5: Man sollte nicht den Videos und Dokumenten trauen, die von Kampagnenbetreibern bereitgestellt werden. Diese Informationen sollte man als eine reine Marketing- und Werbekampagne betrachten und niemals irgendwelchen Versprechungen trauen, vor allem nicht solchen, die unrealistisch oder sehr, sehr schwierig zu erfüllen scheinen. Sätze wie "das weltweit erste", "das weltweit schnellste" oder "das weltweit kleinste" sollten die Unterstützer skeptisch machen.

Mögliche Gegenmaßnahmen der Crowdfunding-Plattform

Was könnte man tun, um solche Situationen zu vermeiden? Oder ist die Crowdfunding-Plattform von Natur aus nicht in der Lage, die Unterstützer zu schützen?

Eigentlich sollte es eine Art Vertrauensverhältnis zwischen allen Akteuren im Spiel geben – ja, es ist ein Spiel beziehungsweise eine Wette! Um das richtige Maß an Vertrauen zu erreichen, muss ein Crowdfunding-Unternehmen folgende Dienstleistungen anbieten:

  • Persönliche Identifizierung aller Kampagnenbesitzer mit offiziellen und legalen Dokumenten wie Pässen, Führerscheinen, Wohnorten. Dies ermöglicht es Unternehmen wie Indiegogo oder Kickstarter, mit den Kampagneninhabern in Kontakt zu bleiben und sie aufzuspüren. Natürlich können Pässe und andere Dokumente gefälscht werden, aber das erfordert einen erheblichen kriminellen Aufwand.
  • Transparenz: Wenn wir bestehende Kampagnen analysieren, ist mangelnde Transparenz eines der größten Probleme. Mit "mangelnder Transparenz" meine ich die Tatsache, dass die Geldgeber oft fast nichts über die Eigentümer der Kampagne wissen. Das hängt mit dem vorherigen Aspekt zusammen: Während die Geldgeber bei Kreditkartenzahlungen garantieren müssen, dass sie vertrauenswürdig sind (was von den Kreditkartenunternehmen überprüft wird), erhalten sie im Gegenzug nur eine winzige Menge an Informationen über die Kampagnenbesitzer. Moment mal! Ich zahle meinen Beitrag an Personen, die größtenteils anonym sind (d. h. sich hinter einer Kampagnen-Website verstecken)? Die Antwort lautet leider ja. Es reicht nicht aus, wenn nur das Crowdfunding-Unternehmen über detaillierte Informationen über die Eigentümer der Kampagne verfügt.
  • Due-Diligence-Maßnahmen würden erfordern, dass ein Crowdfunding-Unternehmen technisch überprüft, ob eine Kampagne bzw. ein Projekt durchführbar ist. Zu diesem Zweck können sie Experten auf dem jeweiligen Gebiet einstellen, um die Behauptungen der Kampagneninhaber zu überprüfen. Darüber hinaus sollten sie den Hintergrund der Kampagnenbesitzer, seien es Unternehmen oder Einzelpersonen, überprüfen. Wenn ein erfolgreiches Unternehmen wie Anker als Eigentümer der Kampagne fungiert, ist die Wahrscheinlichkeit, dass die Backer die angebotenen Vergünstigungen und Belohnungen erhalten, wesentlich höher. Ist der Initiator der Kampagne hingegen unbekannt, ist das Risiko deutlich höher. Wenn man über Kampagnen und ihre Urheber nachdenkt, sollte man auch an deren Verantwortlichkeit denken.
  • Kontrolle und Ausgewogenheit: schrittweise Überweisung der Beiträge anstelle einer vollständigen Zahlung auf einmal. Dies könnte etwas schwierig zu erreichen sein, da von den Kampagneninhabern sicherlich einige Vorabinvestitionen verlangt werden. Dennoch würde ich in diesem Zusammenhang eher die Haltung einer Bank (Crowdfunding-Plattform) und eines Kreditnehmers (Kampagnenbesitzer) erwarten. In jedem Schritt wie Prototyping, Testen, endgültiges Produktdesign, Herstellung und Auslieferung sollte das Crowdfunding-Unternehmen von den Kampagneninhabern Nachweise darüber verlangen, was sie mit den Crowdfunding-Investitionen bisher getan und erreicht haben. Für das Prototyping wird zum Beispiel nur ein kleinerer Geldbetrag benötigt. Wenn sie einen erfolgreichen Prototyp entwickelt haben, können sie mit der Fertigstellung des Produkts fortfahren. Wenn das Produkt fertig ist, geht es weiter mit der Herstellung. Bei jedem Schritt erhalten sie einen vorher festgelegten Prozentsatz der Finanzierung. Darüber hinaus müssen die Kampagneninhaber einen konkreten Zeitplan für alle ihre Aktivitäten vorlegen. Wenn sich ein Schritt verzögert, können keine weiteren Gelder erhalten werden, bis der Schritt abgeschlossen ist. Eine Art Ampel auf der Projektwebsite könnte den aktuellen Risikograd einer Kampagne darstellen.
  • Lieferung: Für jedes Projekt müssen die Kampagneninhaber nachweisen, dass sie die Vergünstigungen und Belohnungen tatsächlich an ihre Unterstützer versandt haben, indem sie entsprechende Dokumente des Lieferdienstes vorlegen. Meiner Erfahrung nach haben einige Kampagnenbetreiber die Vergünstigungen als versandt gekennzeichnet, ohne wirklich etwas zu versenden.
  • Kein Verkauf über andere Kanäle: Bei einigen Kampagnen begannen die Entwickler von Produkten bzw. Lösungen, ihre Produkte oder Lösungen über ihre Websites zu verkaufen, bevor einige Unterstützer ihre Vergünstigungen überhaupt erhalten hatten. Der Vertrag zwischen Unterstützern und Crowdsourcing-Plattformen sollte diese Möglichkeit definitiv ausschließen. Wenn Geldgeber über eine Crowdfunding-Kampagne Geld für die Produktentwicklung ausgeben, müssen sie die ersten sein, die die Produkte und die freigeschalteten Belohnungen erhalten. Darüber hinaus waren einige der verkauften Produkte deutlich billiger als der angegebene UVP. Das sieht nach Betrug aus, riecht nach Betrug und ist Betrug. In solchen Fällen würde ich erwarten, dass die Kampagnenbetreiber Strafen an die Unterstützer zahlen müssen.

Eigene Gegenmaßnahmen

Für Backer bzw. Sponsoren einer Crowdfunding-Kampagne existieren aufgrund der beschriebenen Tatsachen zurzeit nur wenige Möglichkeiten, Risiken zu vermeiden. Eine offensichtliche, wenn auch radikale Option wäre, einfach nicht an Crowdfunding-Kampagnen teilzunehmen. Würden alle Nutzer so verfahren, gingen allerdings Anbieter wie Kickstarter in kürzester Zeit pleite. Zudem hätten die ehrlichen, kleinen Kampagnenbetreiber das Nachsehen, die ohne diese Geldquelle ihre Projekte nicht umsetzen könnten.

Daher ist das erste Gebot, sich über den jeweiligen Kampagnenbetreiber detaillierte Informationen zu beschaffen. Natürlich hat diese Informationsakquise ihre Grenzen. Ist der Kampagnenbetreiber eine renommierte, bekannte Firma, die bereits seit Längerem im Geschäft ist und gute Produkte auf den Markt bringt? Falls ja, dürfte das Risiko erheblich geringer sein als bei "dubiosen" oder mehr oder weniger "anonymen" Geschäftspartnern. Inzwischen nutzen auch renommierte Unternehmen zunehmend die Möglichkeit des Crowdfunding.

Eine weitere Möglichkeit besteht darin, sich auf dem Markt nach ähnlichen Produkten umzusehen. Nicht jedes als innovativ angepriesenes Produkt ist es wirklich. Gibt es bereits stark verwandte Alternativen, sollte man besser zu diesen greifen. Es hat insbesondere Vorteile, Produkte von einem Shop zu beziehen, wenn Käufe dort abgesichert sind wie bei Zahlung über Paypal oder Kreditkarte der Fall.

Fast jedes über Kickstarter oder Indiegogo erworbene Produkt ist nach Beendigung der Kampagne über Stores verfügbar, wenn auch zu höheren Preisen. Die Ersparnis durch Finanzierung einer Kampagne gegenüber dem UVP kann schon einiges ausmachen. In manchen Fallen könnte sich ein Abwarten trotzdem vor allem lohnen, wenn die Differenz zwischen Crowdfunding-Preis und Endpreis eher marginal ist. Abwarten hat auch den Vorteil, dass relativ zeitnah nach Produktveröffentlichungen in der Regel auch einige Produktreviews folgen, denen Interessierte die Vorteile und Nachteile des Produkts entnehmen können. Bei Crowdfunding kauft man schließlich die Katze im Sack.

Teilweise finden sich bei der Websuche auch Bewertungen von Kampagnen, bei denen zum Teil Experten ihre Einschätzung verlautbaren. Diese Quellen erweisen sich oft als sehr hilfreich.

Crowdfunding-Sponsoren sollten sich nicht von virtuellen Demo-Videos oder Lobpreisungen des Anbieters mit Superlativen täuschen lassen. Zeigt ein Demovideo nur das grafisch simulierte Produkt, kann das zwar die einzige Option des Herstellers sein, aber auch ein bewusst produziertes Fake. Beispielsweise hat eine Kampagne für 3D-Drucker den Druckkopf in unterschiedlichen Varianten gezeigt, wovon aber bei den angebotenen Perks nie die Rede war. Aber auch bei der Illustration echter Prototypen ist Vorsicht geboten. Dahinter kann sich schließlich Dummy-Funktionalität verbergen. Stutzig sollten Interessierte werden, wenn das Produkt nie im Detail erscheint. Gehen aus der Beschreibung technische Spezifikationen und die Funktionsweise detailliert hervor, so lässt es sich besser einschätzen als bei vagen, lückenhaften, unrealistischen oder schwammigen Aussagen.

Wie bereits erwähnt, sollten Geldgeber ihre eigene Risikobereitschaft unter die Lupe nehmen. Handelt es sich um höhere Geldbeträge, deren Verlust sehr schmerzhaft wäre, sollte man von einer Kampagne Abstand nehmen. Das ist zugegebenermaßen schwer, weil sich Kampagnen unseren instinktiven Hang nach Vergünstigungen und coolen Gadgets zunutze machen. Es geht darum, unsere Entscheidungen bewusst und vernünftig zu treffen. Eine Nacht darüber zu schlafen, ist hier immer die bessere Option, auch wenn dann statt den Super-Early-Bird-Angeboten nur noch Early-Bird-Angebote übrigbleiben. Es empfiehlt sich, nicht gleich zu dem eigentlichen Produkt alles mögliche Zubehör mitzubestellen. Ist das Projekt erfolgreich, lässt sich Zubehör auch im Nachhinein bestellen. Dadurch bleibt der eingesetzte Geld- beziehungsweise Wettbetrag geringer.

Fazit

Einige mögen argumentieren, dass all diese Maßnahmen die Freiheit der Kampagnenbesitzer einschränken. In dieser Hinsicht haben sie recht. Allerdings besteht derzeit ein Ungleichgewicht zwischen Geldgebern, Kampagneninitiatoren und Crowdfunding-Plattformen, sodass die meisten Risiken bei den Geldgebern liegen. Daher erscheint es mehr als fair, diese Risiken unter allen Beteiligten aufzuteilen. Ich bin der festen Überzeugung, dass sich Crowdfunding zu einer Sackgasse entwickelt, wenn Unternehmen wie Indiegogo weiterhin alle Lasten auf die Unterstützer abwälzen, sich nicht um Betrug kümmern, sich weigern, Sicherheitsnetze zu schaffen, oder die hohe Intransparenz beibehalten. Wenn sie jedoch alle oder zumindest einige der oben genannten Maßnahmen umsetzen, wird sich dies eindeutig als ein Win/Win/Win-Szenario herausstellen.


URL dieses Artikels:
https://www.heise.de/-9297529

Links in diesem Artikel:
[1] mailto:rme@ix.de

Copyright © 2023 Heise Medien

Adblock test (Why?)

  • 07. September 2023 um 18:58

Edge AI: Künstliche Intelligenz auf eingebetteten Systemen nutzen

Von Dr. Michael Stal
Chip auf Mainboard

(Bild: raigvi / Shutterstock)

Eine Artikelserie führt in die Grundlagen von Edge AI ein und zeigt, wie sich künstliche neuronale Netze auf eingebetteten System ausführen lassen.

Wenn Softwareentwicklerinnen und Softwareentwickler von Artificial Intelligence (AI) und Machine Learning (ML) sprechen, meinen sie überwiegend künstliche neuronale Netze (KNN), deren Training und Inferenz vorzugsweise auf leistungsfähiger Enterprise-Hardware erfolgt. Dank Werkzeugen wie TensorFlow Lite (Micro) und Edge Impulse ist es heute möglich, zumindest die Inferenz eines neuronalen Netzes auch auf eingebetteten Systemen mit beschränkten Ressourcen durchzuführen. Dies hat den Charme, dass die Verarbeitung von Daten dort stattfinden kann, wo die Daten auch anfallen. Beispiele hierfür umfassen autonomes Fahren und die Automatisierungstechnik.

In einer dreiteiligen Artikelserie bespreche ich ab dem 18. August 2023 zunächst wichtige KI-Grundlagen (Teil 1), danach die Arbeit mit TensorFlow Lite (Teil 2), und zu guter Letzt die Anwendung des MLOps-Online-Werkzeugs Edge Impulse (Teil 3). Im dritten Teil kommt außerdem der KI-gestützte Entwicklerassistent GitHub Copilot zur Sprache, der das Entwickeln eingebetteter Software erlaubt.

Ziel dieser Rundreise ist es, interessierte Leserinnen und Leser mit KI-Technologien und Werkzeugen für eingebettete Systeme vertraut zu machen, sodass sie eigene Experimente durchführen können.


URL dieses Artikels:
https://www.heise.de/-9234664

Links in diesem Artikel:
[1] mailto:map@ix.de

Copyright © 2023 Heise Medien

Adblock test (Why?)

  • 17. August 2023 um 15:00

Gib mir den REST - Teil 2: Der Client

Von Dr. Michael Stal

Die Verbindung von eingebetteten Systemen und Servern kann über REST-Kommunikation erfolgen

(Bild: pixabay.com)

Wie kommuniziert ein Arduino-Board serverseitig mit einer REST-API, um Sensor-Messungen zu speichern? Nach dem Server in Teil 1 steht die Client-Seite an.

Arduino-Boards oder andere Microcontroller-Boards beziehungsweise eingebettete Systeme oder Einplatinencomputer können mit einer REST-Anwendung kommunizieren, wenn sie einen WiFi- oder Ethernet-Anschluss integrieren. Da ein typischer Anwendungsfall wie der hier vorgestellte überwiegend Messungen mit Sensoren durchführt, erweist eine Echtzeituhr (RTC) als Vorteil. Dadurch lassen sich zusätzlich zu den Messdaten Zeitstempel (Datum und Zeit) hinzufügen, die später eine historische Analyse ermöglichen, etwa den Verlauf der Temperatur über einen bestimmten Zeitraum.

Auch wenn hier vom Arduino Giga die Rede ist, beschränkt sich die Anwendung keineswegs nur auf dieses Board, sondern lässt sich relativ leicht für andere Arduino-, STM- oder ESP-Boards anpassen, für die funktional ähnliche Bibliotheken wie WiFi, WiFiUdp und HTTPClient in der Arduino IDE oder in Visual Studio Code mit PlatformIO-Plug-in bereitstehen.

Notwendig ist ein Sensor von Bosch Sensortec aus der BME-Familie (BME68x, BME58x, BME38x, BME28x), den Maker über I2C oder SPI anschließen. Für das Beispiel kam ein BME688 zum Einsatz, den es als Breakout-Board von verschiedenen Herstellern wie Pomoroni oder Adafruit gibt. Wer möchte, kann auch ein Bosch Development Kit kaufen. Dieses Board besteht aus einem BME688-Adapter, der huckepack auf einem Adafruit Huzzah32 Feather Board (ESP32) sitzt. Das schlägt mit rund 100 Euro zu Buche, hat aber den Charme, sich mittels der kostenlosen BME-AI-Studio-Software trainieren zu lassen. Der Sensor lernt dabei, über ein neuronales Netz verschiedene Gasmoleküle in der Luft zu erkennen, wie Kaffee, CO₂ oder Chlor. Er ermittelt für die Moleküle in der Luft Widerstände in Ohm und kann über die elektrische Charakteristik Gase klassifizieren. Diese spezifischen ML-Trainings sind mit Breakout-Boards freilich nicht möglich – der Anwender erfährt dort nur den Widerstand des Gases ohne Zuordnung zu einem konkreten Molekül. Dafür kosten die einfachen Boards auch nur zwischen 20 und 30 Euro.

Wie bereits im ersten Teil [1] erwähnt, findet sich der Quellcode für die Beispiele in dem GitHub Repository [2].

Ein Hinweis vorab: Als mögliche Alternative für die hier vorgestellte Integration über eine RESTful-Architektur käme beispielsweise der Einsatz von MQTT infrage, das eine ereignis- beziehungsweise nachrichtenorientierte Kommunikation zwischen Client und Server ermöglicht. In vielen Fällen, vielleicht auch für den hier vorliegenden, ist MQTT eine sehr gute Option. Allerdings fokussieren sich die beiden Artikelteile speziell darauf, Kommunikation und Backend-Integration über REST-APIs zu veranschaulichen. Ein vom Backend betriebener Microservice stellt schließlich typischerweise eine REST-API bereit.

Das Hardware-Setup

In der konkreten Schaltung sind die folgenden Verbindungen notwendig:

Arduino ........ BME688

3.3V ............ Vin

GND ............. GND

SCL ............. SCK

SDA ............. SDI

Folgendes Fritzing-Diagramm veranschaulicht dies:

Die Verbindung des BME688-Sensors und dem Arduino läuft über I2C oder SPI. Im vorliegenden Fall ist I2C das Mittel der Wahl

Die Arduino-Anwendung

Beim Entwickeln der Arduino-Software sind folgende Verantwortlichkeiten zu beachten:

Initiales Setup:

  • Verbindung zum WiFi-Netz aufbauen
  • Über NTP-Server die aktuelle Zeit einlesen und die Echtzeituhr (RTC) einstellen
  • Verbindung zum I2C-Sensor BME688 aufbauen

Kontinuierliche Loop:

  • Messergebnisse vom BME688 auslesen
  • Lokale Zeit über RTC ermitteln
  • JSON-Nachricht zusammenbauen
  • Mit REST-Server über WiFi/HTTP verbinden
  • POST-Nachricht schicken
  • Prüfen, ob die Paketsendung erfolgreich war

Nebenbei soll der Sketch Informationen über den seriellen Monitor zu Test- und Beobachtungszwecken ausgeben.

Verbindung zum WLAN

Der Arduino-Sketch erwartet im selben Verzeichnis eine Datei arduino_secrets.h, die Definitionen für das gewünschte WLAN enthalten, konkret die SSID und den WLAN-Key. Für die Nutzung des Arduino-WiFis bedarf es einer entsprechenden WiFi-Bibliothek, deren Header wir inkludieren, zum Beispiel: #include <WiFi.h>. Zusätzlich benötigen wir die Bibliothek ArduinoHttpClient, die wir über den Library Manager der Arduino IDE oder VS Code & PlatformIO installieren.

Den Verbindungsaufbau zum WLAN übernimmt nachfolgender Code:


void setup() {
  // Seriellen Stream starten
  Serial.begin(9600);

  // Verbindungsaufbau WiFi
  while (status != WL_CONNECTED) {
    Serial.print("Versuche Verbindungsaufbau zum WLAN-Netz: ");
    Serial.println(ssid);                   // print the network name (SSID);

    // Verbinden mit WPA/WPA2 Netzwerk:
    status = WiFi.begin(ssid, pass);
  }

  // Name des WLANs nach erfolgtem Verbindungsaufbau:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
NTP Protokoll

Anschließend soll der Zugriff auf einen NTP-Server zum Einstellen der Echtzeituhr verhelfen.

Beim Giga R1 Board sind dazu folgende Header-Dateien notwendig:

#include <WiFiUdp.h>      // zum Versenden von NTP-Paketen notwendig
#include <mbed_mktime.h>

Das schaut auf anderen Boards natürlich anders aus und wäre diesbezüglich zu ändern.

Der eigentliche Code für das Setzen der Echtzeituhr befindet sich in der Methode setNtpTime(), die ihrerseits eine UDP-Verbindung mit einem lokalen Port öffnet, ein Anfragepaket an den gewünschten Zeitserver verschickt (sendNTPacket()), um danach die Antwort über parseNtpPacket() zu empfangen, zu verarbeiten und die Echtzeituhr mit der aktuellen Zeit einzustellen. Hat dies erfolgreich geklappt, lässt sich fortan über die Methode getLocalTime() stets die aktuelle Zeit aus der Echtzeituhr auslesen. Zurückgeliefert wird jeweils ein Datetime-String, der sich aus Datum und Zeit zusammensetzt: „2023-06-05 12:31:45“.

// NTP-Anfrage senden, Antwort erhalten und parsen
void setNtpTime()
{
    status = WL_IDLE_STATUS;
    Udp.begin(localPort);
    sendNTPpacket(timeServer);
    delay(1000);
    parseNtpPacket();
}

// Rufe einen Zeitserver auf 
unsigned long sendNTPpacket(const char * address)
{
    memset(packetBuffer, 0, NTP_PACKET_SIZE);
    packetBuffer[0] = 0b11100011; // LI, Version, Modus
    packetBuffer[1] = 0; // Stratum, Art der Uhr
    packetBuffer[2] = 6; // Abfrageintervall
    packetBuffer[3] = 0xEC; // Präzision der Uhr
    // 8 Bytes von Nullen für Root Delay & Root Dispersion
    packetBuffer[12] = 49;
    packetBuffer[13] = 0x4E;
    packetBuffer[14] = 49;
    packetBuffer[15] = 52;

    Udp.beginPacket(address, 123); // NTP Aufrufe erfolgen über Port 123
    Udp.write(packetBuffer, NTP_PACKET_SIZE);
    Udp.endPacket();
}

// Hier wird das NTP-Antwortobjekt empfangen und geparst:
unsigned long parseNtpPacket()
{
    if (!Udp.parsePacket())
        return 0;

    Udp.read(packetBuffer, NTP_PACKET_SIZE); // Paket vom NTP-Server empfangen
    const unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    const unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
    const unsigned long secsSince1900 = highWord << 16 | lowWord;
    constexpr unsigned long seventyYears = 2208988800UL;
    const unsigned long epoch = secsSince1900 - seventyYears;
    set_time(epoch);

// Folgende ausführliche Beschreibung lässt sich ausgeben,
// sobald man DETAILS definiert
#if defined(DETAILS)
    Serial.print("Sekunden seit Jan 1 1900 = ");
    Serial.println(secsSince1900);

    // NTP time in "echte" Zeit umwandeln:
    Serial.print("Unix Zeit = ");
    // Ausgabe der Unix time:
    Serial.println(epoch);

    // Stunde, Minute, Sekunde ausgeben:
    Serial.print("Die UTC Zeit ist "); // UTC entspricht Greenwich Meridian (GMT)
    Serial.print((epoch % 86400L) / 3600); // Stunde ausgeben (86400 sind die Sekunden pro Tag)
    Serial.print(':');
    if (((epoch % 3600) / 60) < 10) {
        // In den ersten 10 Minuten einer Stunde brauchen wir eine führende Null
        Serial.print('0');
    }
    Serial.print((epoch % 3600) / 60); // Minute ausgeben (3600 = Sekunden pro Stunde)
    Serial.print(':');
    if ((epoch % 60) < 10) {
        // In den ersten 10 Minuten einer Stunde brauchen wir eine führende Null
        Serial.print('0');
    }
    Serial.println(epoch % 60); // Sekunde ausgeben
#endif

    return epoch;
}

// Lokale Zeit mittels RTC (Real Time Clock) ermitteln:
String getLocaltime()
{
    char buffer[32];
    tm t;
    _rtc_localtime(time(NULL), &t, RTC_FULL_LEAP_YEAR_SUPPORT);
    strftime(buffer, 32, "%Y-%m-%d %k:%M:%S", &t);
    return String(buffer);
}

Für Interessierte, die mehr über das NTP (Network Time Protocol) erfahren möchten, eine Abbildung mit anschließenden Erläuterungen, die den Aufbau eines NTP-Pakets veranschaulichen:

Mit dem NTP-Protokoll können eingebettete Systeme ihre Echtzeituhr setzen

Die Header-Einträge eines NTP-Pakets gestalten sich oben wie folgt:

LI

Leap Indicator (2 bits)

Dieses Attribut zeigt an, ob die letzte Minute des aktuellen Tages eine Zusatzsekunde benötigt.

0: Keine Sekundenanpassung nötig

1: Letzte Minute soll 61 sec haben

2: Letzte Minute soll 59 sec haben

3: Uhr wird nicht synchronisiert

VN

NTP-Versionsnummer (3 Bits) (etwa Version 4).

Mode

NTP-Paketmodus (3 Bits)

0: Reserviert

1: Symmetrisch aktiv

2: Symmetrisch passiv

3: Client

4: Server

5: Broadcast

6: NTP-Kontrollnachricht

7: Für private Nutzung reserviert

Stratum

Stratum-Ebene der Zeitquelle (8 bits)

0: Unspezifiziert oder ungültig

1: Primärer Server

2–15: Sekundärer Server

16: Unsynchronisiert

17–255: Reserviert

Poll

Poll Interval (8-Bit Ganzzahl mit Vorzeichen), die in Sekunden definiert, was das maximale Zeitintervall zwischen aufeinander folgenden NTP-Nachrichten sein soll.

Precision

Präzision der Uhr (8-Bit Ganzzahl mit Vorzeichen)

Root Delay

Die Round-Trip-Verzögerung vom Server zur primären Zeitquelle. Es handelt sich um eine 32-Bit Gleitpunktzahl, die Sekunden festlegt. Der Dezimalpunkt befindet sich zwischen Bits 15 und 16. Sie ist nur für Server-Nachrichten relevant.

Root Dispersion

Der maximale Fehler aufgrund der Toleranz bezüglich der Uhr-Frequenz. Es handelt sich um eine 32-Bit Gleitpunktzahl, die Sekunden festlegt. Der Dezimalpunkt befindet sich zwischen Bits 15 und 16. Sie ist nur für Servernachrichten relevant

Reference Identifier

Bei Stratum-1-Servern beschreibt dieser Wert (ein ASCII-Wert mit 4 Bytes) die externen Referenzquellen. Für sekundäre Server beschreibt der Wert (4 Bytes) die IPv4-Adresse der Synchronisationsquelle, oder die ersten 32 Bit des MDA-Hashes (MDA = Message Digest Algorithm 5) der IPv6-Adresse des Synchronisationsservers.

Der Sensor

Um den BME688-Sensor über I2C anzusteuern, müssen wir Bibliotheken von Adafruit über den Bibliotheksmanager laden - der Code lässt sich einfach umstellen, um stattdessen SPI zu verwenden. Importieren muss man die Bibliotheken Adafruit BME680 und Adafruit Unified Sensor. Es kann natürlich auch die Bibliothek eines anderen Sensors aus der BME-Familie von Bosch sein, etwa die eines BME280.

Die Initialisierung des Sensors ist in setup() integriert. Hier die Vereinbarung des BME-Proxies:

Adafruit_BME680 bme; // Vereinbarung der Variablen bme

Und hier die eigentliche Initialisierung:

  // Verbindung mit Sensor BME680 etablieren
  if (!bme.begin()) {
    Serial.println(F("Konnte keinen Sensor finden. Bitte Schaltung überprüfen!"));
    while (1);
  }

  // Oversampling-Werte setzen und IIR-Filter initialisieren
  bme.setTemperatureOversampling(BME680_OS_8X);
  bme.setHumidityOversampling(BME680_OS_2X);
  bme.setPressureOversampling(BME680_OS_4X);
  bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
  bme.setGasHeater(320, 150); // 320*C für 150 ms
}

Ab geht die POST

Die Methode createJSONString() konstruiert aus Messdaten und Zeitstempel ein JSON-Objekt. Ich habe hier bewusst ein manuelles Erstellen gewählt, statt ArduinoJson zu verwenden, weil der Aufwand sehr übersichtlich bleibt:

// Hier wird ein String generiert, der ein JSON-Objekt enthält
String createJSONString(double temp, double humi, double pres, double resi, String date, String time) {
  String result = "{";
  const String up = "\"";
  const String delim = ",";
  const String colon = ":";

  result += up + "temperature" + up + colon + String(temp,2) + delim;
  result += up + "humidity"    + up + colon + String(humi,2) + delim;
  result += up + "pressure"    + up + colon + String(pres,2) + delim;
  result += up + "resistance"  + up + colon + String(resi,2) + delim;
  result += up + "date"        + up + colon + up + date + up + delim;
  result += up + "time"        + up + colon + up + time + up;
  result += "}";
  return result;
}

Wer einen Sensor besitzt, der einige dieser Messdaten nicht enthält, stutzt das JSON-Objekt entsprechend. In der Server-Datenbank wird für jedes nicht übergebene Attribut einfach ein null eingetragen.

Für das Versenden der Messdaten über HTTP-POST ist callAPIPost() verantwortlich, das anschließend auch die Antwort des Servers ausgibt, der im Erfolgsfall mit Status-Code 200 antwortet:

// Hier erfolgt die Vorbereitung und die eigentliche Durchführung des POST-Aufrufes / REST-PUSH 
void callAPIPost(double temperature, double humidity, double pressure, double resistance, const String& date, const String& time){
  Serial.println("Durchführung eines neuen REST API POST Aufrufs:");
  String contentType = "application/json"; // Wir übergeben ein JSON-Objekt

  // JSON Nutzlast (Body) kreieren
  String postData = createJSONString(temperature, humidity, pressure, resistance, date, time);
  Serial.println(postData); // ... und ausgeben

  // Per WiFi-Verbindung POST aufrufen und dabei "application/json" und das JSON-Objekt übergeben
  client.post("/measurements/api", contentType, postData);

  // Status und Body aus Antwort extrahieren
  int statusCode = client.responseStatusCode();
  String response = client.responseBody();

  // Ausgabe der Ergebnisse:
  Serial.print("Status code: ");
  Serial.println(statusCode);
  Serial.print("Antwort: ");
  Serial.println(response);
}

Aufrufe der vorgenannten Methoden finden in der loop()-Methode statt, außer natürlich die Initialisierungen beim Programmstart.

Läuft der Sketch, verbindet er sich über WiFi mit dem WLAN, misst kontinuierlich Daten vom BME688 und übermittelt sie und einen Zeitstempel als JSON-Objekt per POST an den Server

Fazit

Damit ist der Arduino-Sketch fertig, der den REST-Server aus Teil 1 mit neuen Messungen versorgt. Natürlich gibt es wie immer Erweiterungsmöglichkeiten:

  • So ließe sich ein SSD1306-OLED-Display hinzufügen, das die jeweiligen Messwerte ausgibt. Oder ein SD-Karten-basierter Datenlogger. Ein Beispiel für die zusätzliche Integration eines OLED-Displays mit IIC-Anschluss findet sich ebenfalls auf dem oben erwähnten GitHub Repository. Der Sensor und das I2C-Display sind per Daisy-Chain hintereinander geschaltet. Gegebenenfalls muss man die IIC-Adresse (default: 0x3C) und die Auflösung (default: 128x64) für die eigene Konfiguration ändern.

Das am IIC-Bus seriell angeschlossene SSD1306-Display (128 x 64) gibt die Daten der aktuellen Messung aus

Hier werden der Anschluss für 3.3V, GND, SDA, SCL vom Arduino auf ein Breadboard geführt, von wo sie IIC-Display und IIC-Sensor abgreifen können.

  • Denkbar ist das Nutzen anderer Klimasensoren wie BME280, BME580 oder sogar anderer Typen von Sensoren. Das erfordert Änderungen sowohl am Client- als auch am Server-Code.
  • Wer verschiedene Boards mit Sensoren besitzt, könnte dem Datenschema Attribute wie Board-Kennung und GPS-Daten mitgeben.
  • Es könnten alternative Boards wie Raspberry Pi Picos, ESP32-Boards zum Einsatz kommen. Sogar das direkte Anschließen eines BME688 an den Mac OS/Windows/Linux-Computer ist über ein GPIO-Erweiterungsboard möglich [3].
  • Eine App fürs Handy oder Tablet könnte den aktuellen Messverlauf grafisch visualisieren.

Und das ist immer noch nicht das Ende der Fahnenstange. Die Möglichkeiten sind fast unendlich. Client- und Server-Anwendungen des Beispiels sollten das Vorgehen dabei gut veranschaulichen und zu eigenen Experimenten anreizen. Die Implementierungen für Client und Server lassen sich entsprechend anpassen.

Ich hoffe jedenfalls, der hier vorgestellte Showcase bietet viel Nutzen und macht Spaß.


URL dieses Artikels:
https://www.heise.de/-9179967

Links in diesem Artikel:
[1] https://www.heise.de/blog/Gib-mir-den-REST-Teil-1-Der-REST-Server-9179764.html
[2] https://github.com/ms1963/RESTCommunication
[3] https://www.heise.de/blog/Fernsteuerung-per-Computer-GPIO-Breakout-Boards-als-Schweizer-Taschenmesser-7091889.html
[4] mailto:rme@ix.de

Copyright © 2023 Heise Medien

Adblock test (Why?)

  • 05. Juli 2023 um 15:40

Apple Vision Pro: Einsatz in geschäftlichen und industriellen Anwendungen

Von heise online

Kult oder Kultur? Apple's Vision Pro Konzept.

(Bild: apple.com)

Der Blog möchte nicht auf einen fahrenden Zug aufspringen, sondern erläutern, wie sich das Konzept der Vision Pro in industriellen Umgebungen nutzen lässt.

Auf der diesjährigen WWDC 2023 (World Wide Developer Conference) von Apple hat Tim Cook die seit Jahren "sagenumwobene" Vision Pro Brille vorgestellt. Auf YouTube finden sich hierzu viele Videos, weshalb sich dieser kurze Beitrag eine Wiederholung der dortigen Erkenntnisse spart.

Eines vorweg: es geht hier nicht primär um Apple und sein neuestes Produkt, sondern um die Betrachtung des zugrundeliegenden Konzepts und seiner möglichen Einsatzgebiete.

Aber etwas Kontext muss trotzdem sein: Jedenfalls soll die Vision Pro dank vieler Sensoren und Kameras sowie einer Auflösung von 4K für die beiden Bildschirme ein Augmented Reality der Zukunft bieten. Apple nennt dies bewusst Spatial Computing (räumliche Verarbeitung) statt auf überfrachtete Terminologie wie AR (Augmented Reality) oder MR (Mixed Reality) zurückzugreifen. So lassen sich im realen Raum virtuelle Hintergründe oder Umgebungen integrieren, in deren Kontext Anwender ihre Arbeits- oder Entertainment-Umgebung gestalten können. Der Grad an Virtualität ist also nach eigenem Gusto steuerbar.

Mit einem veranschlagten Preis von 3500 US-Dollar gehört das neue Gadget nicht gerade zu den Schnäppchen. Was aber viele übersehen: Apple sieht sich hier nicht im Wettbewerb mit Giganten wie Meta und deren Oculus-Produktfamilie, sondern adressiert eher das Marktsegment, das auch die 3200-US-Dollar teure Hololens von Microsoft abdeckt. Und das sind eher Businessanwender und vielleicht ein paar Technologie-Junkies mit großem Sparstrumpf. Ein Spielzeug für Gamer ist die Brille also nicht. Daher ist zu erwarten, dass Apps für die Vision Pro ebenfalls dieses Marktsegment adressieren und sich nicht unbedingt im unteren Preissegment tummeln.

Brille für industrielle Anwendungen

Nach Ansicht des Autors könnte das Produkt gerade für geschäftliche und industrielle Umgebungen interessant sein. So erschließt das Konzept folgende Domänen und Anwendungsfälle:

  • Wartungsszenarien: Hier nutzen Wartungsspezialisten die Brille, um sich in der Fabrik oder Anlage interne Details zu gerade betrachteten Komponenten in der Brille anzeigen zu lassen oder generell Hilfe für die Wartung zu erhalten.
  • Medizinische Geräte: Über Wartungsszenarien für Modalitäten oder für Labordiagnostik hinaus könnten Ärzte die Brille für die Befundung verwenden, etwa in Zusammenhang mit einem Bildarchivierungssystem.
  • Navigations- und Logistikanwendungen: Für mobile Wartungsexperten und Lagermitarbeiter wäre der Einsatz der Vision Pro denkbar, um sich an die richtigen Orte leiten zu lassen.
  • Bedienen und Beobachten: In der Industrieautomatisierung wäre ein Konzept überlegenswert, das ein Bedienen oder Beobachten einzelner SPSen (Speicher Programmierbare Steuerungen), SCADA-Systeme und anderer Systeme ermöglicht.
  • Kreativität: Eine Vision Pro ließe sich für den Entwurf neuer Schaltungen, Architekturen und künstlicher Artefakte einsetzen, an denen Anwender weitgehend ohne Ablenkung virtuell arbeiten könnten.
  • Militär: Dass sich die Vision Pro für militärische Anwendung zweckentfremden ließe, steht außer Frage, etwa für die Anzeige wichtiger Informationen auf dem Feld.

Gerade die Mobilität der Brille erweist sich in diesen Szenarien als Vorteil, mal abgesehen von dem signifikanten Nachteil, dass der separat erhältliche Hochleistung-Akku gerade mal zwei Stunden durchhält. Natürlich stellt all das nur die Spitze des Eisbergs dar. Da noch niemand die Vision Pro in der Praxis prüfen konnte, gibt es viel Raum für reine Spekulation. Interessierte Entwicklungsschmieden und User sollten sich trotzdem schon jetzt ein paar Gedanken über mögliche Anwendungen machen.

All das führt natürlich unweigerlich zu Überlegungen hinsichtlich von Software- und Systemarchitektur der entsprechenden Systeme und Anwendungen. Auch die Kombination mit KI in einer Spatial-Computing-Anwendung könnte sinnvoll sein, etwa für die visuelle Einschätzung möglicher Fehlerursachen bei der Systemwartung.

Die Apple Vision Pro [1] ließe sich ergo als wichtiger Bestandteil neuer oder geänderter Anwendungsfelder etablieren. Ob die Konkurrenz dem etwas entgegensetzen will beziehungsweise kann, bleibt abzuwarten. Zumindest sollte das Konzept Entwickler und Anwender anregen, wie sie diese Art von Produkt sinnvoll und produktiv in ihren Domänen oder für sich selbst nutzen können. Die Zukunft beginnt jetzt.


URL dieses Artikels:
https://www.heise.de/-9181574

Links in diesem Artikel:
[1] https://www.heise.de/news/Apples-Vision-Pro-Apples-Mixed-Reality-Headset-enthuellt-9168785.html
[2] mailto:rme@ix.de

Copyright © 2023 Heise Medien

Adblock test (Why?)

  • 12. Juni 2023 um 14:15

Gib mir den REST – Teil 1: Der REST-Server

Von heise online

(Bild: Bogdan Vija / Shutterstock.com)

Wie kommuniziert ein Arduino-Board serverseitig mit einer REST API, um Sensor-Messungen über ein objektrelationales Mapping zu speichern?

Arduino-Boards, die über eine optionale Echtzeituhr (RTC = Real Time Clock) und ein WiFi-Modul verfügen, lassen sich ins Internet der Dinge integrieren, etwa über die Arduino Cloud oder AWS. Wer lieber On-premises agieren möchte, kann anders vorgehen und Server beziehungsweise Clients im heimischen Netz zur Verfügung stellen. Das bringt den Vorteil mit sich, immer die Kontrolle über die Bereitstellung (Deployment) zu behalten. Wie Entwicklerinnen und Entwickler dabei vorgehen können, zeigen dieser und der nachfolgende Artikel. Während zunächst die Server-Anwendung zur Sprache kommt, dreht sich der zweite Teil um die eingebetteten Clients.

Gleich vorweg: alle Implementierungsdateien liegen auf GitHub [1] parat. Eine gute Gelegenheit, um sich mühselige Handarbeit zu ersparen.

Grobe Systemarchitektur

Im Beispielsszenario kommen ein Arduino Board mit C++-Sketch und ein Server mit Java und Spring Boot 3 zum Einsatz.

Die folgende Abbildung zeigt die Systemarchitektur:

Ein Arduino-Client kommuniziert mit der REST-API auf dem Server

Auf der linken Seite der Grafik ist das Arduino-Board, konkret ein Arduino Giga R1 WiFi, zu sehen. Verwendbar sind aber grundsätzlich alle Arduino-Boards oder Arduino-unterstützte Boards wie etwa ein ESP32. Am Arduino ist ein BME688-Sensor von Adafruit über I2C oder SPI angeschlossen. Der Arduino-Sketch macht periodisch Messungen von Temperatur, Feuchtigkeit, Luftdruck und Gaswiderstand, und verschickt das Ergebnis zusammen mit dem von der Echtzeituhr ausgelesenen Zeitstempel über einen POST-Aufruf an den Server: <hostname>:8080/measurement/api. <hostname> kann dabei die IP-Adresse oder der DNS- beziehungsweise Server-Name sein.

Serverseitig (rechte Seite in der Abbildung) fungiert eine in Java geschriebene Spring-Boot-3-REST-Anwendung als Kommunikationspartner für das Arduino-Board. Die zugehörige Datenbank läuft auf PostgreSQL, das die Anwendung als Docker-Container bereitstellt. So ist sichergestellt, dass Entwicklerinnen und Entwickler PostgreSQL auf dem eigenen Computer nicht extra installieren müssen.

Zur Laufzeit sendet das Arduino-Board POST-Nachrichten an den Server. Der dazugehörige REST-Endpunkt sorgt dann dafür, dass die Messung in die Datenbank übernommen wird.

Der Server

Selbstverständlich lassen sich auch andere Datenbankmanagementsysteme nutzen, etwa mysql (maria). In diesem Fall müssten nur die Konfigurationsdateien application.yml sowie docker-compose.yml angepasst werden. Und in der Konfigurationsdatei pom.xml – das Projekt nutzt Maven für den Build-Prozess – sind entsprechend die PostgreSQL-Referenzenen durch die für die alternative Datenbank notwendigen Abhängigkeiten (<dependencies>) zu ersetzen. Wie aus folgender Abhängigkeits-Festlegung ersichtlich, gilt das nur für die zweite Abhängigkeit in Bezug auf PostgreSQL – in diesem Fall den pgJDBC-Treiber. Der soll übrigens nur zur Laufzeit aktiv sein, deshalb ist der benötigte Scope in der pom.xml-Datei mit runtime festgelegt. Alle anderen Abhängigkeiten beziehen sich auf Spring Boot, im Detail auf die Nutzung von Spring Web, Spring Data JPA (Java Persistence API) und Spring Test:

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.postgresql</groupId>
			<artifactId>postgresql</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

Als Adapter nutzt die Server-Anwendung einen über die URL [2] bereitstehenden JDBC-Treiber.

Für den Fall, dass Entwickler und Entwicklerinnen bereits eine lokale Instanz von postgreSQL einsetzen, ist in der Konfiguration des Docker-Containers ein Port-Mapping definiert. Dieses verbindet den Server-Port 5332 mit dem Container-Port 5432 und verhindert somit Konflikte mit lokalen postgreSQL-Installationen, die auf Port 5432 lauschen.

Sobald der Arduino-Client einen POST-Aufruf mit einer Messung auf die Reise schickt, nimmt die Server-Schnittstelle die Messung als JSON-Body im jeweiligen REST-POST-Endpunkt entgegen und speichert die Messdaten in der postgreSQL-Datenbank measurement.

Die REST-Anwendung nutzt Port 8080, was sich in der Konfigurationsdatei application.yml bequem ändern lässt.

server:
  port: 8080

#turn off the web server
spring:
  datasource:
    url: jdbc:postgresql://localhost:5332/measurement
    username: michael
    password: michael
  jpa:
    hibernate:
      ddl-auto: create-drop
    properties:
      hibernate:
        dialect: org.hibernate.dialect.PostgreSQLDialect
        format_sql: true
    show-sql: true
  main:
    web-application-type: servlet
Inbetriebnahme

Wer einfach loslegen will, startet nach Download der Quellen zunächst das Docker-Image. Dazu ist es erforderlich, auf dem eigenen Server beziehungsweise Desktop Docker zu installieren. Mittels der -> URL [3] bedeutet das zunächst, die entsprechende Docker-Implementierung für Linux, Windows oder macOS herunterzuladen und zu starten. In der Werkzeugleiste des Betriebssystems erscheint danach das für Docker typische Icon, ein Container-Frachtschiff.

Im nächsten Schritt sollten Entwickler und Entwicklerinnen die Konfiguration docker-compose.yml auf ihre Bedürfnisse anpassen:

services:
  db:
    container_name: postgres
    image: postgres
    environment:
      POSTGRES_USER: michael
      POSTGRES_PASSWORD: michael
      PGDATA: /data/postgres
    volumes:
      - db:/data/postgres
    ports:
      - "5332:5432"
    networks:
      - db
    restart: unless-stopped
networks:
  db:
    driver: bridge

volumes:
  db:

Am Anfang der Konfiguration sind die bereitgestellten Dienste spezifiziert. Als Basis soll der Container das auf Docker Hub bereitgestellte Postgres-Image verwenden.

Im Bereich environment erfolgt die Festlegung den Anwendernamens und des zugehörigen Passworts sowie des Ordners im Container, der die PostgreSQL-Dateien enthalten soll. Das interne Netzwerk heißt db und ist über eine Bridge erreichbar. Stoppt der Container, löscht er die Datenbanktabelle.

Wer ein anderes DBMS nutzt, muss diese YAML-Datei entsprechend anpassen.

Im Ordner, in dem die YAML-Datei liegt, erfolgt nun der Start des Containers über

%docker compose up -d

Nach Eingabe von

%docker container ls

in der Kommandozeile müsste der Container auftauchen:

CONTAINER ID   IMAGE      COMMAND                  CREATED       STATUS       PORTS                    NAMES​
d0cc2733c93a   postgres   "docker-entrypoint.s…"   4 hours ago   Up 4 hours   0.0.0.0:5332->5432/tcp   postgres​

Damit ist es allerdings nicht getan, denn es fehlt noch die Datenbank für die Messungen.

Zunächst öffnen wir dazu eine Shell im Container für den interaktiven Zugriff:

docker exec -it postgres bash

In der Container-Session ist im Falle von postgreSQL das Kommando:

psql - U michael

notwendig, wobei U für den Nutzer steht. Ohne Änderungen ist im Beispiel michael als Benutzername und Passwort für postgreSQL voreingestellt.

Über psql lassen sich mit \l die existierenden Datenbanken abrufen.

Hier erscheint in etwa die folgende Ausgabe:

Name     |  Owner  | Encoding |  Collate   |   Ctype    | ICU Locale | Locale Provider |  Access privileges  ​
-------------+---------+----------+------------+------------+------------+-----------------+---------------------​
libc            | ​
 michael     | michael | UTF8     | en_US.utf8 | en_US.utf8 |            | libc            | ​
 postgres    | michael | UTF8     | en_US.utf8 | en_US.utf8 |            | libc            | ​
 template0   | michael | UTF8     | en_US.utf8 | en_US.utf8 |            | libc            | =c/michael         +​
             |         |          |            |            |            |                 | michael=CTc/michael​
 template1   | michael | UTF8     | en_US.utf8 | en_US.utf8 |            | libc            | =c/michael         +​
             |         |          |            |            |            |                 | michael=CTc/michael
(4 rows)

Um eine neue Datenbank zu erzeugen, geben wir

CREATE DATABASE measurement;

ein.

Achtung: Der Strichpunkt ist unbedingt erforderlich. Mit \c measurement verbinden wir uns mit der Datenbank und können danach mit \dt die vorhandenen Tabellen beziehungsweise Datenbankschemas analysieren. Noch ist dort nichts zu sehen, weil für das Datenbankschema die Spring-Boot-3-Anwendung sorgt. Spring Boot kreiert zu diesem Zweck selbständig folgendes SQL-DDL-Kommando:

    create table measurement (​
       id integer not null,​
        date date,​
        humidity float(53),​
        pressure float(53),​
        resistance float(53),​
        temperature float(53),​
        time time,​
        primary key (id)​
    )​

Wer eine professionelle IDE wie IntelliJ IDEA Ultimate nutzt, kann viele der beschriebenen und kommenden Schritte bequem über die IDE anstoßen.

Nun müssen wir noch die Java-basierte Spring-Boot-3-Anwendung starten (mittels Main.class), wobei wir eine ähnliche Ausgabe wie die folgende erhalten sollten – nur die letzten zwei Zeilen sind hier abgebildet.

…. noch viel mehr ….

2023-06-04T15:18:01.952+02:00 INFO 51585 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''

2023-06-04T15:18:01.959+02:00 INFO 51585 --- [ main] de.stal.Main : Started Main in 3.172 seconds (process running for 3.807)

Es ist aus der Konsolenausgabe ersichtlich, dass Spring Boot für Webanwendungen automatisch den eingebetteten Web-Server Tomcat startet. Alternativ könnten wir auch Jetty nutzen, was folgende Konfigurationsänderung im pom.xml von Maven erfordert:

<dependency>​
    <groupId>org.springframework.boot</groupId>​
    <artifactId>spring-boot-starter-web</artifactId>​
    <exclusions>​
        <exclusion>​
            <groupId>org.springframework.boot</groupId>​
            <artifactId>spring-boot-starter-tomcat</artifactId>​
        </exclusion>​
    </exclusions>​
</dependency>​
<dependency>​
    <groupId>org.springframework.boot</groupId>​
    <artifactId>spring-boot-starter-jetty</artifactId>​
</dependency><dependency>​
    <groupId>org.springframework.boot</groupId>​
    <artifactId>spring-boot-starter-web</artifactId>​
    <exclusions>​
        <exclusion>​
            <groupId>org.springframework.boot</groupId>​
            <artifactId>spring-boot-starter-tomcat</artifactId>​
        </exclusion>​
    </exclusions>​
</dependency>​
<dependency>​
    <groupId>org.springframework.boot</groupId>​
    <artifactId>spring-boot-starter-jetty</artifactId>​
</dependency>​

In der Ausgabe befindet sich des Weiteren eine Warnung über Views, die wir in diesem Fall aber getrost ignorieren können.

Im Falle von gradle als Build-Tool wäre es stattdessen:

configurations {​
    compile.exclude module: "spring-boot-starter-tomcat"​
}​

dependencies {​
    compile("org.springframework.boot:spring-boot-starter-web:2.0.0.BUILD-SNAPSHOT")​
}

Das aber nur am Rande, weil das Beispielsprojekt wie schon erwähnt Maven einsetzt.

Immer wenn der Postman klingelt

Möchte man den Server auch ohne Arduino-Client testen, leistet die Anwendung Postman [4] hierfür gute Dienste. Sie ermöglicht das Aufrufen von APIs und benutzt curl als Basis dafür.

Mit postman lassen sich bequem REST-APIs testen

Das implementierte REST-Beispiel unterstützt folgende Aufrufe von REST-Endpunkten, um CRUD-Funktionalität (CRUD = Create Read Update Delete) bereitzustellen.

  • POST-Aufrufe dienen zum Anlegen neuer Messungen über hostname:port/measurements/api, wobei im Body ein JSON-Objekt mit den Messergebnissen enthalten sein muss.
  • GET-Aufrufe wie hostname:port/measurements/api brauchen keinen Body im HTTP-Paket (none). Der Endpunkt liefert die Liste aller gespeicherten Messungen zurück. Das gilt auch für das Auslesen von individuellen Einträgen über hostname:port/measurements/api/42. In diesem Fall beziehen wir uns auf die Messung mit der Id 42.
  • Der PUT-Aufruf wie etwa hostname:port/measurements/api/1 benötigt ein JSON-Objekt als Body, das die Werte des zum Datenbankeintrag gehörigen Primärschlüssels 1 aktualisiert.
  • Ein DELETE-Aufruf wie zum Beispiel hostname:port/measurements/api/2 löscht den Eintrag mit dem Primärschlüssel 2 aus der Datenbank. Ebenso wie bei GET ist kein Body (none) vonnöten.

Ein Beispiel für ein mitgeliefertes JSON-Objekt bei POST- oder PUT-Aufrufen könnte wie folgt aussehen:

{​
  “temperature“: 23.5,​
  “humidity“: 12.7,​
  “pressure“: 990.5,​
  “resistance“: 23.8,​
  "date“: “2023-06-10“,​
  “time“: “06:24:56“​
}​
Let’s Spring-boot

Für die eigentliche Magie in der Server-Anwendung sorgt Spring Boot 3. Laut der Spring-Seite gilt für Spring Boot:

"Das Spring Framework bietet ein umfassendes Programmier- und Konfigurationsmodell für moderne Java-basierte Unternehmensanwendungen – auf jeder Art von Einsatzplattform.

Ein Schlüsselelement von Spring ist die infrastrukturelle Unterstützung auf der Anwendungsebene: Spring konzentriert sich auf das "Klempnerhandwerk" von Unternehmensanwendungen, sodass sich die Teams auf die Geschäftslogik auf Anwendungsebene konzentrieren können, ohne unnötige Bindungen an bestimmte Bereitstellungsumgebungen."

Das Java-Framework integriert einen Webserver mit Servlet-Unterstützung (Tomcat oder optional Jetty), über den es die REST-API im Web beziehungsweise Netzwerk zur Verfügung stellt. Die ganze Servlet-Maschinerie bleibt Entwicklerinnen und Entwicklern erspart. Zudem bietet es eine Repository-Schnittstelle, mit deren Hilfe die REST-Endpunkte neue Einträge beispielsweise speichern, ändern, löschen oder abrufen. Außerdem sorgt es über Annotationen für das objekt-relationale Mapping zwischen der measurement-Datenbanktabelle und dem entsprechenden Java-Objekt.

In IntelliJ Ultimate findet sich Unterstützung für die Arbeit mit Docker und Spring Boot

In der Datei Main.java (siehe Listing unten) ist die Klasse Main als @SpringBootApplication annotiert. Das sorgt dafür, dass Spring Boot nach Komponenten und Entitäten sucht und weitere Handarbeiten automatisch erledigt. Gleichzeitig fungiert die Klasse auch als @RestController, weshalb sich in ihr REST-Endpunkte befinden müssen. Mittels der Annotation @RequestMapping("measurements/api") legt man fest, welches Prefix jeder REST-Endpunkt bekommen soll. Externe Aufrufe beginnen dann immer mit diesem Prefix, also zum Beispiel GET <hostname>:8080/measurements/api. Der Konstruktur der Klasse Main enthält als Parameter ein MeasurementRepository, über das die REST-Endpunkte Aktionen auf dem aktuellen persistierten Objekt durchführen, etwa um eine neue Messung in der Datenbank zu speichern:

public Main(MeasurementRepository measurementRepository) {​
        this.measurementRepository = measurementRepository;​
}​

Die Schnittstelle MeasurementRepository erzeugt Spring Boot automatisch und übergibt sie per Dependency Injection an den Konstruktor. Es ist dementsprechend als @Repository definiert und leitet sich von JpaRepository ab. Die zwei Typparameter von JpaRepository beziehen sich auf die Persistenzklasse für Datenbankeinträge (Measurement) und auf den Datentyp des Primärschlüssels (Integer):

@Repository​
public interface MeasurementRepository​
        extends JpaRepository<Measurement, Integer> {​
}​

Einer der definierten REST-Endpunkte ist etwa folgendes parametrisiertes GET:

@GetMapping("{id}")​
public Optional<Measurement> getMeasurementById(@PathVariable("id") Integer id)​

Die GetMapping-Annotation sorgt dafür, dass beim GET-Aufruf des Endpunkts mit der URL <hostname>:port/measurements/api/3 die Methode das entsprechende Datenbankobjekt mit Primärschlüssel 3 zurückliefert. Sie nimmt dabei das angesprochene MeasurementRepository zu Hilfe:

return measurementRepository.findById(id);

Wichtig in Zusammenhang mit REST-Endpunkten ist die Tatsache, dass bei Rückgaben von Ergebnissen Spring Boot dafür sorgt, diese zuvor in ein JSON-Objekt umzuwandeln – es wären im Übrigen auch andere Formate möglich. Zugleich erwartet jeder REST-Endpunkt, dass ihm entsprechende Messergebnisse im Body des HTTP-Pakets als JSON-Objekte übergeben werden. Das ist insbesondere bei POST und PUT notwendig, gilt aber nicht für in der URL angegebene Parameter wie etwa die gewünschte Id des "REST-Objektes" (siehe GET und DELETE). Letztere wird als Parameter in die URL integriert, zum Beispiel: localhost:8080/measurements/api/12

package de.stal;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@RestController
@SpringBootApplication
@RequestMapping("measurements/api")
public class Main {

    private final MeasurementRepository measurementRepository;

    public Main(MeasurementRepository measurementRepository) {
        this.measurementRepository = measurementRepository;
    }

    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }

    @GetMapping
    public List<Measurement> getMeasurement() {
        return measurementRepository.findAll();
    }

    @GetMapping("{id}")
    public Optional<Measurement> getMeasurementById(@PathVariable("id") Integer id){
        return measurementRepository.findById(id);
    }

    @PostMapping
    public void addMeasurement(@RequestBody NewMeasurementRequest request) {
        Measurement measurement = new Measurement();
        measurement.setDate(request.date);
        measurement.setTime(request.time);
        measurement.setTemperature(request.temperature);
        measurement.setHumidity(request.humidity);
        measurement.setPressure(request.pressure);
        measurement.setResistance(request.resistance);
        measurementRepository.save(measurement);
    }

    record NewMeasurementRequest(
            java.sql.Date date,
            java.sql.Time time,
            Double temperature,
            Double humidity,
            Double pressure,
            Double resistance
    ){}

    @DeleteMapping("{measurementId}")
    public void deleteMeasurement(@PathVariable("measurementId") Integer id) {
        measurementRepository.deleteById(id);
    }

    // assignment
    @PutMapping("{measurementId}")
    public void updateMeasurement(@PathVariable("measurementId") Integer id,
                               @RequestBody NewMeasurementRequest msmUpdate) {
        Measurement existingMeasurement = measurementRepository.findById(id)
                .orElseThrow();
        existingMeasurement.setDate(msmUpdate.date);
        existingMeasurement.setTime(msmUpdate.time);
        existingMeasurement.setTemperature(msmUpdate.temperature);
        existingMeasurement.setHumidity(msmUpdate.humidity);
        existingMeasurement.setPressure(msmUpdate.pressure);
        existingMeasurement.setResistance(msmUpdate.resistance);


        measurementRepository.save(existingMeasurement);
    }

}

Die Klasse Measurement.java (siehe Listing unten) definiert die eigentliche Entität, die über ein objektrelationales Mapping mit der Datenbank verbunden ist. Dementsprechend enthält die Klasse eine @Entity-Annotation.

Wer IntelliJ IDEA oder eine andere fortschrittliche IDE nutzt, kann "Boilerplate"-Code wie Setters, Getters, toString(), equals(), hashcode() und Konstruktoren von der IDE generieren lassen. Andernfalls ist manuelles Eintippen nötig, was sich bei späteren Refactoring-Maßnahmen als umständlich erweist.

Nicht zu vergessen: Die Klasse Measurement benötigt einen parameterlosen Konstrukteur mit leerem Rumpf, damit das objektrelationale Mapping von Spring Boot aus JSON-Nachrichten Java-Objekte generieren kann.

Die Datenfelder der Klasse Measurement entsprechen den gewünschten Attributen des Datenbankeintrags, in unserem Fall Temperatur, Feuchtigkeit, Luftdruck, Gaswiderstand, Datum und Zeit. Den Primärschlüssel Integer id lassen wir Spring Boot für das Datenbanksystem automatisch generieren. Dazu dienen die Annotationen: @Id, @SequenceGenerator und @GeneratedValue. Der Primärschlüssel soll mit 1 starten und bei jedem neuen Datenbankeintrag um 1 hochgezählt werden. Die Annotation @id weist das gleichnamige Datenfeld als Primärschlüssel aus.

package de.stal;

import jakarta.persistence.*;

import java.sql.Date;
import java.sql.Time;
import java.util.Objects;

@Entity
public class Measurement {

    @Id
    @SequenceGenerator(
            name = "measurement_id_sequence",
            sequenceName = "measurement_id_sequence",
            allocationSize = 1
    )
    @GeneratedValue(
            strategy = GenerationType.SEQUENCE,
            generator = "measurement_id_sequence"
    )
    private Integer id;
    private Double temperature;
    private Double humidity;
    private Double pressure;
    private Double resistance;
    private java.sql.Date date;
    private java.sql.Time time;

    public Measurement(Integer id, Double temperature, Double humidity, Double pressure, Double resistance, Date date, Time time) {
        this.id = id;
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        this.resistance = resistance;
        this.date = date;
        this.time = time;
    }

    public Measurement() {
    }

    @Override
    public String toString() {
        return "Measurement{" +
                "id=" + id +
                ", temperature=" + temperature +
                ", humidity=" + humidity +
                ", pressure=" + pressure +
                ", resistance=" + resistance +
                ", date=" + date +
                ", time=" + time +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Measurement that = (Measurement) o;
        return Objects.equals(id, that.id) && Objects.equals(temperature, that.temperature) && Objects.equals(humidity, that.humidity) && Objects.equals(pressure, that.pressure) && Objects.equals(resistance, that.resistance) && Objects.equals(date, that.date) && Objects.equals(time, that.time);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, temperature, humidity, pressure, resistance, date, time);
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Double getTemperature() {
        return temperature;
    }

    public void setTemperature(Double temperature) {
        this.temperature = temperature;
    }

    public Double getHumidity() {
        return humidity;
    }

    public void setHumidity(Double humidity) {
        this.humidity = humidity;
    }

    public Double getPressure() {
        return pressure;
    }

    public void setPressure(Double pressure) {
        this.pressure = pressure;
    }

    public Double getResistance() {
        return resistance;
    }

    public void setResistance(Double resistance) {
        this.resistance = resistance;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public Time getTime() {
        return time;
    }

    public void setTime(Time time) {
        this.time = time;
    }
}

Um die (Web-Server-)Anwendung zu konfigurieren, gibt es eine YAML-Datei mit dem Namen application.yml im resources-Ordner:

server:
  port: 8080

#turn off the web server
spring:
  datasource:
    url: jdbc:postgresql://localhost:5332/measurement
    username: michael
    password: michael
  jpa:
    hibernate:
      ddl-auto: create-drop
    properties:
      hibernate:
        dialect: org.hibernate.dialect.PostgreSQLDialect
        format_sql: true
    show-sql: true
  main:
    web-application-type: servlet

Hier legen Entwickler und Entwicklerinnen unter anderem Port, Passwort und Benutzername fest, zudem die URL zum Zugriff auf die PostgreSQL-Datenbank. Benutzername und Passwort müssen mit der korrespondierenden Konfiguration in docker-compose.yml übereinstimmen. Mit ddl-auto weisen wir Spring Boot JPA an, die Tabelle measurement zu löschen, falls die Anwendung beziehungsweise Session terminiert (drop measurement). Über web-application-type: servlet bestimmt die Konfiguration, dass wir zum Bereitstellen unserer REST-API einen Webserver benötigen, der Java-Servlets unterstützt. Das können Tomcat oder Jetty sein.

Damit wären wir am Ende der notwendigen Java- und Konfigurationsdateien angekommen. Der Gesamtumfang aller Dateien liegt bei rund 250 Codezeilen zuzüglich Konfigurationsfestlegungen und inklusive der mittels IDE (IntelliJ IDEA) generierten Codes. Der Aufwand, um kleinere REST-APIs zu entwickeln, hält sich daher dank Spring Boot in Grenzen.

Fazit

Durch Spring Boot fällt es leicht, recht schnell und effizient eine REST-API zusammenzubauen. Natürlich gäbe es auch Alternativen wie Quarkus oder Micronaut, aber Spring Boot ist sehr verbreitet und besitzt eine große Community. Das Beispiel ist für die Übergabe von Messungen des BME688 festgelegt. Es ist allerdings sehr leicht, die Anwendung für andere Sensoren oder andere Zwecke auszulegen.

  • Denkbar ist zum Beispiel der Anschluss mehrerer Boards mit Sensoren. Dafür müssten Entwicklerinnen und Entwickler die Messungsobjekte mit dem Attribut Client-ID ausstatten sowie weitere beziehungsweise andere Attribute hinzufügen.
  • Denkbar wäre es auch, das Datenbanksystem und/oder die Spring-Anwendung in die Cloud (AWS, Azure) zu laden. Dafür bedarf es allerdings zuerst eines Sicherheitskonzepts, etwa mit Hilfe von OAuth2 und JWT (Java Web Token).
  • Auch weitere REST-Endpunkte wären möglich. Dementsprechend repräsentiert das hier beschriebene Beispiel lediglich einen von vielen möglichen Anwendungsfällen.

Während sich dieser Beitrag auf die Server-Seite fokussiert hat, beschreibt der in Kürze nachfolgende Teil 2, wie sich auf Microcontroller-Boards wie dem Arduino Giga die dazu passenden REST-Clients erstellen lassen.


URL dieses Artikels:
https://www.heise.de/-9179764

Links in diesem Artikel:
[1] https://github.com/ms1963/RESTCommunication
[2] https://jdbc.postgresql.org/
[3] https://www.docker.com
[4] https://www.postman.com/
[5] mailto:map@ix.de

Copyright © 2023 Heise Medien

Adblock test (Why?)

  • 07. Juni 2023 um 14:43

Fernsteuerung per Computer: GPIO-Breakout-Boards als Schweizer Taschenmesser

Von heise online

(Bild: Adafruit)

GPIO-Breakout-Boards wie das Adafruit FT232H ermöglichen den Zugriff auf elektronische Schaltungen von einem Computer.

Um von einem Computer aus auf Elektronikkomponenten zuzugreifen, existieren verschiedene Wege. Zum einen lassen sich Mikrocontroller über USB dazwischenschalten, um beispielsweise auf Arduino-Boards oder Raspberry Pi mittels einer auf den Boards laufenden Software die Elektronik zu kontrollieren. Für Arduino-kompatible Boards lässt sich zu diesem Zweck eine Firmata-Firmware installieren, die den mehr oder weniger direkten Zugriff auf Ports des Boards ermöglicht.

Eine weitere Option ist die RESTful-Kommunikation von einem Computer zu einem autonomen Mikrocontroller-Board, um über diesen Umweg auf Elektronik zuzugreifen. Das Programm auf dem Board fungiert als Vermittler zwischen Computer und Elektronik.

Ein dritter Weg besteht darin, ein sogenanntes GPIO-Breakout-Board über USB an den betreffenden Computer anzuschließen. In diesem Fall können Anwendungen direkt auf die am Breakout-Board befindlichen GPIO-Ports zugreifen. Zudem implementiert ein GPIO-Breakout-Board meistens Unterstützung für Protokolle wie SPI oder I2C. Dadurch ist auch das Ansteuern etwas komplexerer Hardware – zum Beispiel Displays und Sensoren – möglich.

Das Adafruit FT232H GPIO Breakout Board

Ein solches GPIO-Breakout-Board ist das Adafruit FT232H Breakout Board Blinka, das zu Straßenpreisen von rund 15 bis 18 Euro erhältlich ist, etwa bei BerryBase [1]. Es gibt natürlich auch andere GPIO-Boards, aber das Untersuchte besitzt eine ausreichende Zahl von GPIO-Ports und unterstützt zudem UART, I2C, SPI, Bit-Bang und JTAG. Entwicklerinnen und Entwickler können es über Python vom Computer aus ansteuern. Zudem sind für das FT232H-Board viele Informationsquellen verfügbar.

Für meine Experimente habe ich die neueste Variante des Boards erworben, die über einen USB-C-Port und einen Stemma-QT-Konnektor verfügt, der den Anschluss entsprechender Komponenten mit STEMMA/QT- beziehungsweise Qwiic-Interface erlaubt.

Die neueste Version des Breakout-Boards bietet einen USB-C-Anschluss und einen Quiic/STEMMA-QT-Anschluss.

(Bild: Adafruit)

Die ältere Version des Boards kann lediglich mit einem Micro-USB-Anschluss aufwarten.

(Bild: Adafruit)

En detail

Das Board ist nach dem integrierten Chip benannt, einem FT232H von FTDI, der auch das komplette USB-Protokoll implementiert. Dadurch müssen sich Entwickler nicht mit systemnaher USB-Funktionalität herumschlagen. Im vielen Fällen ist keine Installation eines USB-Treibers auf dem Computer notwendig. Der FT232H unterstützt USB 2.0 Hi-Speed, was Übertragungsraten bis 480 MBit/s gewährleistet – im ebenfalls verfügbaren Full-Speed-Modus sind es stattdessen maximal 12 MBit/s. Die neue Boardversion besitzt einen USB-C-Port. Ein passendes Kabel findet sich nicht im Lieferumfang. Daher empfiehlt es sich, gleich ein entsprechendes Kabel mit zu bestellen, sofern nicht bereits vorhanden.

Der Chip-Kern arbeitet mit 1,8V, die Ein-/Ausgänge mit 3,3V. Letztere sind tolerant gegenüber 5V. Noch genauere Details finden sich auf dem Produktblatt des Chip-Herstellers [2].

Wie im Pinout-Diagramm ersichtlich (siehe obige Abbildungen), stellt die Adafruit-Lösung die GPIO-Ports D4-D7 sowie C0-C7 bereit.

Die Ports D0-D3 implementieren das SPI- oder das I2C-Protokoll. Das "oder" will sagen, dass zur Ansteuerung entweder I2C oder SPI verfügbar ist, aber nicht beides gleichzeitig.

Mit einem Schalter auf dem Board bestimmen Entwickler, ob sie I2C nutzen aber nicht SPI (Schalterstellung I2C auf on), oder ob sie SPI nutzen möchten aber nicht I2C (Schalterstellung I2C auf off). Im letzteren Fall gilt: D0 -> SCLK, D1 -> MOSI, D2 -> MISO, D3 -> CS0. Im ersteren Fall wiederum gibt es folgende Zuordnung: D0 -> SCL, D1 oder D2 -> SDA. Hierbei lässt sich einer der beiden Ports D1 und D2 nutzen, um das SDA-Signal von I2C zu übertragen. In der alten Version des Boards mussten Anwender für I2C noch den Port D1 mit dem Port D2 verdrahten, um dann D2 mit der eigentlichen Schaltung zu verbinden.

Installation

Zur Installation des Boards stellt Adafruit eine eigene Webseite mit Anleitung zur Verfügung [3]. Wichtig ist die Tatsache, dass die Programmierung auf dem Windows-, Mac- oder Linux-Computer eine Installation von Python 3 [4] und pip3 [5] erfordert.

Da Windows keine treiberlosen USB-Geräte unterstützt, müssen Anwender zunächst einen USB-Treiber von Zadig [6] installieren. Bei macOS und Linux ist das in den allermeisten Fällen nicht notwendig.

Danach folgen auf allen Betriebssystemen zum Zugriff über CircuitPython noch Installationen der libusb-Bibliothek sowie der speziellen Python-Bibliotheken pyftdi und adafruit-blinka – Blinka ist übrigens auch der Name des Breakout-Boards. Schließlich müssen noch udev-Rules (Linux only) festgelegt und eine Umgebungsvariable (alle Betriebssysteme) definiert werden. Diese Variable heißt BLINKA_FT232H und soll bei einem Wert von 1 das Vorhandensein eines Blinka-Boards signalisieren.

Wie bereits oben erwähnt, ist hier immer vorausgesetzt, dass auf dem Computer eine Installation von python3 und pip3 vorliegt.

Das Board wird übrigens ohne "vormontierte" Header ausgeliefert. Zunächst ist daher etwas Lötarbeit erforderlich.

Hier die verschiedenen Anleitungen:

Zur Ansteuerung von Schaltungen über das Breakout-Board Blinka muss dieses natürlich an den eigenen Computer angeschlossen sein. Softwaretechnisch dienen CircuitPython-Programme als Schnittstelle zum Board. Standard-Computer unter Windows, Linux, macOS verstehen zwar Python 3, aber wie können Entwickler CircuitPython nutzen? Dafür bedarf es zum einen der Blinka-Bibliothek für Python (adafruit-blinka) und entsprechender CircuitPython-Bibliotheken für die "ferngesteuerte" Hardware wie Sensoren, Bildschirme und dergleichen:

Der Computer benötigt eine Python3-Installation plus diverse Bibliotheken, um Schaltungen beziehungsweise Komponenten ansteuern zu können.

(Bild: Adafruit)

Da ich zum Test des Blinka-Boards einen Mac-Computer benutzt habe, folgen nun exemplarisch die für macOS notwendigen Installationsschritte im Detail:

Sollte noch keine Installation des Package Managers Homebrew vorhanden sein, installieren wir ihn mittels:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Anschließend ist die Installation von libusb mit Hilfe von Homebrew erforderlich:

brew install libusb

Danach die von pyftdi:

pip3 install pyftdi

Und im letzten Schritt das Installieren der eigentlichen Board-Bibliothek:

pip3 install adafruit-blinka

Nun sollte die Anwenderin die Umgebungsvariable BLINKA_FT232H mit 1 belegen:

export BLINKA_FT232H=1

Zu guter Letzt gilt es noch, die Python 3 REPL-Umgebung zu starten und schrittweise die folgenden zwei Anweisungen einzugeben:

import board
dir(board)

Verlief alles fehlerlos, gibt letztere Instruktion die Liste der verfügbaren Pins auf dem Terminal aus.

Fertig ist die Installation!

Zum Prüfen ob die Installation funktioniert, gibt es folgende Tests:

Zunächst ein Test, um sicherzustellen, dass das System das FT232H-Board erkennt:

from pyftdi.ftdi import Ftdi

Ftdi().open_from_url('ftdi:///?')

Normalerweise gibt es nur einen FTDI-Controller, weshalb die Ausgabe wie folgt aussehen könnte:

>>> from pyftdi.ftdi import Ftdi

>>> Ftdi().open_from_url('ftdi:///?')[Link auf https://learn.adafruit.com/circuitpython-on-any-computer-with-ft232h/setup] [11]

Available interfaces:

ftdi://ftdi:232h:1/1 ()/code/p pcodePlease specify the USB device/code/p pDanach eine Verifikation, ob die Umgebungsvariable vorhanden und korrekt gesetzt ist:/p pcodeimport os/code/p pcodeos.environ["BLINKA_FT232H"]/code/p pDie Ausgabe müsste schlicht lauten:/p pre class="rte__tx--listing"codestrong´1´/strong/code/pre pWie gesagt, diese Beschreibung kratzt nur an der Oberfläche. Die genauen Anweisungen lassen sich a href="https://learn.adafruit.com/circuitpython-on-any-computer-with-ft232h/setup" rel="external noopener" target="_blank"strongauf der Anleitungs-Website von Adafruit nachvollziehen [12]/strong/a./p pSollte es Probleme geben, finden sich auf der a href="https://learn.adafruit.com/circuitpython-on-any-computer-with-ft232h/troubleshooting" rel="external noopener" target="_blank"strongAdafruit-Website Post-Install-Checks [13]/strong/a entsprechende Hinweise./p h3 class="subheading" id="nav_programmierung_3"Programmierung/h3 pIch spare mir Beispiele für das obligatorische LED-Blinken oder das Erkennen des Zustands eines Druckknopfes. Stattdessen soll der Anschluss eines a href="https://sensirion.com/de/produkte/katalog/SHT40" rel="external noopener" target="_blank"strongSensirion SHT40 [14]/strong/a als Beispiel dienen./p pDieser Sensor kostet nur wenige Euro und misst Temperatur und Feuchtigkeit relativ präzise. Die typische Genauigkeit bei der relativen Luftfeuchtigkeit beträgt 1,8% RH und bei der Temperatur 0,2°C. Verwendung findet in diesem Zusammenhang ein Adafruit-Board mit I2C-Anschluss. Das Messen kann entweder mit oder ohne Heizen (-gt;codesht.mode/code) erfolgen. Für das Programmbeispiel habe ich auf das Heizen verzichtet. Da es sich um ein I2C-basiertes Sensorboard handelt, ist der I2C-Switch des FT232H auf ON zu stellen./p figure class="a-inline-image a-u-inline" div img alt class="legacy-img " decoding="async" height="522" loading="eager" src="https://heise.cloudimg.io/width/696/q85.png-lossy-85.webp-lossy-85.foil1/_www-heise-de_/imgs/18/3/5/4/2/8/9/0/BildDerSchaltung-3584313b6978b464.JPG" srcset="https://heise.cloudimg.io/width/336/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/3/5/4/2/8/9/0/BildDerSchaltung-3584313b6978b464.JPG 336w, https://heise.cloudimg.io/width/1008/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/3/5/4/2/8/9/0/BildDerSchaltung-3584313b6978b464.JPG 1008w, https://heise.cloudimg.io/width/1392/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/3/5/4/2/8/9/0/BildDerSchaltung-3584313b6978b464.JPG 2x" width="696" /div figcaption class="a-caption " p class="a-caption__text" /pdiv class="text"An das Breakout-Board wird über ein Qwiic/STEMMA-QT-Kabel der Sensirion SHT40 angeschlossen./div /figcaption /figure pDer Sensor benötigt nach jeder Messung etwa vier Sekunden Verschnaufpause – zwei Sekunden bei der Temperaturmessung und vier Sekunden bei der Feuchtigkeitsmessung. Deshalb enthält die while-Schleife ein codesleep(4)/code./p pVor dem Programmstart müssen Entwickler noch die benötigte Bibliothek von Adafruit installieren:/p pre class="rte__tx--listing"pip3 install adafruit-circuitpython-sht4x/pre pDas vorliegende Programmbeispiel stammt im Original von Adafruit./p h3 class="subheading" a-code language="python" pre class="rte__tx--listing listing"codeimport time # zum Verzögern der Ausgaben import board # zur Ausgabe über FT232H import adafruit_sht4x # Einbinden der Bibliothek für den Sensor i2c = board.I2C() # Am I2C-Anschluss (SDA/SCL des FT232H) hängt ein Adafruit SHT40-Breakout-Board sht = adafruit_sht4x.SHT4x(i2c) print("SHT4X mit folgender Seriennummer entdeckt: ", hex(sht.serial_number)) sht.mode = adafruit_sht4x.Mode.NOHEAT_HIGHPRECISION # ohne Heizen! # alternativ mit: sht.mode = adafruit_sht4x.Mode.LOWHEAT_100MS print("Augenblicklicher Modus: ", adafruit_sht4x.Mode.string[sht.mode]) while True: temperature, relative_humidity = sht.measurements print("Temperatur: %0.1f C" % temperature) print("Feuchtigkeit: %0.1f %%" % relative_humidity) print("") time.sleep(4) # 4 Sekunden Verzögerung/code/pre /a-code /h3 pDie Bildschirmausgabe gestaltet sich wenig spannend wie folgt:/p figure class="a-inline-image a-u-inline" div img alt class="legacy-img " decoding="async" height="463" loading="eager" src="https://heise.cloudimg.io/width/696/q85.png-lossy-85.webp-lossy-85.foil1/_www-heise-de_/imgs/18/3/5/4/2/8/9/0/BildBildschirmausgabeBeispiel-59de146e93e58830.PNG" srcset="https://heise.cloudimg.io/width/336/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/3/5/4/2/8/9/0/BildBildschirmausgabeBeispiel-59de146e93e58830.PNG 336w, https://heise.cloudimg.io/width/1008/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/3/5/4/2/8/9/0/BildBildschirmausgabeBeispiel-59de146e93e58830.PNG 1008w, https://heise.cloudimg.io/width/1392/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/3/5/4/2/8/9/0/BildBildschirmausgabeBeispiel-59de146e93e58830.PNG 2x" width="696" /div figcaption class="a-caption " p class="a-caption__text" /pdiv class="text"Bildschirmausgabe mit den Messwerten des Sensirion SHT40./div /figcaption /figure h3 class="subheading" id="nav_vorsicht_geboten_4"Vorsicht geboten/h3 pEine Warnung müssen Entwicklerinnen und Entwickler unbedingt berücksichtigen. Beim Anschluss von Komponenten an das Breakout-Board sollten sie sicherstellen, dass die jeweilige Schaltung keine Gefahr für den USB-Port darstellt. Ansonsten könnte eine Überlastung am USB-Port des Computers diesen in Mitleidenschaft ziehen. Adafruit weist darauf hin, dass das Board maximal 400-500mA aus dem USB-Port ziehen darf. Dafür gibt es diverse Abwehrmaßnahmen – darunter: Testen, die Absicherung gegenüber induktiver Lasten mittels Dioden, das Begrenzen von Stromstärken mittels Widerständen. Wer das vergisst, könnte den angeschlossenen Computer schädigen. Wie heißt es so schön: Vorsicht ist die Mutter der Porzellankiste./p h3 class="subheading" id="nav_fazit_5"Fazit/h3 pGPIO-Breakout-Boards wie das Adafruit FT232H bieten eine sehr gute Möglichkeit, von Computern aus direkt auf Elektronik zuzugreifen, ohne ein Mikrocontroller-Board dazwischenschalten zu müssen. Das hat natürlich auch Grenzen hinsichtlich der möglichen Anwendungen. Beispielsweise erlauben Mikrocontroller-basierte Lösungen im Vergleich zu ihren PC-Pendants Echtzeitanforderungen und sind hinsichtlich der Verwendung verschiedener Protokolle wesentlich flexibler. Auf der anderen Seite besitzt eine Computer-gestützte Lösung ebenfalls Vorteile. Chip-Hersteller FTDI nennt unter anderem die Ansteuerung von Kameraschnittstellen, Bar-Code-Lesern, Settop-Boxen, Flash-Card-Lesern, MP3-Geräten sowie industrielle Anwendungen als mögliche Beispiele./p pSchön wäre neben der Unterstützung für CircuitPython das Bereitstellen von C- beziehungsweise C++-Bibliotheken, um das Board auch in entsprechenden Anwendungen zu nutzen. Das ist allerdings Jammern auf hohem Niveau. Für die Arten von Anwendungen, die für einen FT232H in Frage kommen, reicht Python völlig aus. Speziell für das Rapid Prototyping eigener Experimente weist Python einige Vorteile auf./p p !-- RSPEAK_STOP -- !-- RSPEAK_START -- /p hr p strongURL dieses Artikels:/strongbr smallcodehttps://www.heise.de/-7091889/code/small /p p strongLinks in diesem Artikel:/strongbr smallcodestrong[1]/strongnbsp;https://www.berrybase.de/adafruit-ft232h-breakout-general-purpose-usb-zu-gpio-spi-i2c/code/smallbr smallcodestrong[2]/strongnbsp;https://ftdichip.com/products/ft232hq//code/smallbr smallcodestrong[3]/strongnbsp;https://learn.adafruit.com/circuitpython-on-any-computer-with-ft232h/setup/code/smallbr smallcodestrong[4]/strongnbsp;https://www.python.org/downloads//code/smallbr smallcodestrong[5]/strongnbsp;https://www.activestate.com/resources/quick-reads/how-to-install-and-use-pip3//code/smallbr smallcodestrong[6]/strongnbsp;https://zadig.akeo.ie//code/smallbr smallcodestrong[7]/strongnbsp;https://learn.adafruit.com/circuitpython-on-any-computer-with-ft232h/windows/code/smallbr smallcodestrong[8]/strongnbsp;https://learn.adafruit.com/circuitpython-on-any-computer-with-ft232h/linux/code/smallbr smallcodestrong[9]/strongnbsp;https://learn.adafruit.com/circuitpython-on-any-computer-with-ft232h/mac-osx/code/smallbr smallcodestrong[10]/strongnbsp;https://cdn-learn.adafruit.com/downloads/pdf/circuitpython-on-any-computer-with-ft232h.pdf/code/smallbr smallcodestrong[11]/strongnbsp;https://learn.adafruit.com/circuitpython-on-any-computer-with-ft232h/setup/code/smallbr smallcodestrong[12]/strongnbsp;https://learn.adafruit.com/circuitpython-on-any-computer-with-ft232h/setup/code/smallbr smallcodestrong[13]/strongnbsp;https://learn.adafruit.com/circuitpython-on-any-computer-with-ft232h/troubleshooting/code/smallbr smallcodestrong[14]/strongnbsp;https://sensirion.com/de/produkte/katalog/SHT40/code/smallbr smallcodestrong[15]/strongnbsp;mailto:map@ix.de/code/smallbr /p p class="printversion__copyright" emCopyright © 2023 Heise Medien/em /p pstronga href="https://blockads.fivefilters.org"Adblock test/a/strong a href="https://blockads.fivefilters.org/acceptable.html"(Why?)/a/p

  • 10. Mai 2023 um 10:25

Mikrocontroller-Board: Das neue Arduino-Board Giga R1 WiFi

Von heise online
!-- RSPEAK_STOP -- figure class="aufmacherbild" img src="https://heise.cloudimg.io/cdn/n/n/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/BoardMitBlinkenderLED-f4ae17bc9d5347eb.gif" srcset="https://heise.cloudimg.io/cdn/n/n/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/BoardMitBlinkenderLED-f4ae17bc9d5347eb.gif 700w, https://heise.cloudimg.io/cdn/n/n/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/BoardMitBlinkenderLED-f4ae17bc9d5347eb.gif 1050w, https://heise.cloudimg.io/cdn/n/n/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/BoardMitBlinkenderLED-f4ae17bc9d5347eb.gif 1200w" sizes="(min-width: 80em) 43.75em, (min-width: 64em) 66.66vw, 100vw" alt class="img-responsive" figcaption class="akwa-caption" p class="caption akwa-caption__text"Das Arduino Gioga R1 WiFi Board ist das bisher leistungsstärkste Board in der Familie von Arduino-Boards für Maker/p p class="source akwa-caption__source"(Bild:nbsp;(c) arduino.cc)/p /figcaption /figure !-- RSPEAK_START -- p strongDas neue Board Arduino Giga R1 WiFi hat denselben Formfaktor wie die Mega-Boards von Arduino, denen es aber in allen Belangen technisch überlegen ist./strong /p pWeil es gerade en vogue zu sein scheint, starte ich mit dem obligatorischen Hintergrundwissen von ChatGPT zum Giga R1. Meine Anfrage an ChatGPT lautete "Schreibe einen Artikel zum Arduino Giga R1":/p p"Der Arduino Giga R1 ist eine Weiterentwicklung der beliebten Arduino-Plattform, die speziell für den Einsatz in professionellen und industriellen Anwendungen entwickelt wurde. Diese neueste Version des Arduino-Boards bietet zahlreiche Verbesserungen und Funktionen, die es zu einer leistungsstarken und flexiblen Lösung für eine Vielzahl von Projekten machen./p pEine der auffälligsten Verbesserungen beim Arduino Giga R1 ist seine erhöhte Leistungsfähigkeit. Das Board ist mit einem leistungsstarken 32-Bit-ARM-Mikrocontroller ausgestattet, der in der Lage ist, hohe Rechengeschwindigkeiten zu erreichen und eine Vielzahl von Anwendungen zu unterstützen. Dies ermöglicht es dem Arduino Giga R1, komplexe Anwendungen wie Bild- und Spracherkennung sowie maschinelles Lernen zu unterstützen./p pEine weitere wichtige Verbesserung beim Arduino Giga R1 ist seine erweiterte Konnektivität. Das Board verfügt über eine Vielzahl von Schnittstellen, einschließlich Ethernet, USB, CAN-Bus und RS485. Diese Schnittstellen ermöglichen es dem Board, mit anderen Geräten und Systemen zu kommunizieren und eine nahtlose Integration in eine breite Palette von Anwendungen zu ermöglichen./p pDarüber hinaus verfügt der Arduino Giga R1 über eine umfangreiche Bibliothek von Bibliotheken und Tools, die es Entwicklern erleichtern, Anwendungen für das Board zu erstellen. Diese Bibliotheken umfassen eine Vielzahl von Funktionen, einschließlich Sensorsteuerung, Datenerfassung, Datenanalyse und drahtloser Konnektivität. Dies ermöglicht es Entwicklern, komplexe Anwendungen schnell und einfach zu erstellen und anzupassen."/p pDoch damit genug zu den erstaunlich präzisen ChatGPT-Erkenntnissen./p h3 class="subheading" id="nav_warum_giga__0"Warum Giga?/h3 pDer Name "Giga" soll wohl darauf hinweisen, dass das neue Mikrocontroller-Board in allen Belangen wesentlich mehr leisten kann als ein Arduino Mega-Board. Das betrifft die eingesetzten Prozessoren, die Art und Zahl der Schnittstellen und etliches mehr. Arduino Giga und Mega haben den Formfaktor gemeinsam. Zum detaillierten Leistungsspektrum des Giga komme ich später noch. Auch vom Preislichen (68,70 Euro im offiziellen Arduino-Store) ähnelt der Arduino Giga mehr seinen Arduino-Pro-Cousins aus der Portenta-Serie und reiht sich damit zwischen den Produktfamilien Arduino und Arduino Pro ein. Es erreicht den Benutzer mit einem unten angebrachten transparenten Acrylboden, der zur (elektrischen) Absicherung dient, plus einer anschließbaren Antenne für drahtlose Kommunikation./p figure class="a-inline-image a-u-inline" div img alt class="legacy-img " decoding="async" height="656" loading="eager" src="https://heise.cloudimg.io/width/696/q85.png-lossy-85.webp-lossy-85.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/BoardVorderseiteAlsDiagrammMitTabelle-94d60c203035a126.png" srcset="https://heise.cloudimg.io/width/336/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/BoardVorderseiteAlsDiagrammMitTabelle-94d60c203035a126.png 336w, https://heise.cloudimg.io/width/1008/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/BoardVorderseiteAlsDiagrammMitTabelle-94d60c203035a126.png 1008w, https://heise.cloudimg.io/width/1392/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/BoardVorderseiteAlsDiagrammMitTabelle-94d60c203035a126.png 2x" width="696" /div figcaption class="a-caption " p class="a-caption__text" /pdiv class="text"Das Arduino Giga R1 WiFi Board besitzt zahlreiche Komponenten und Anschlüsse, darunter einen leistungsstarken ARM-Prozessor von ST Microelectronics mit einem M4- und einem M7-Kern/div p class="a-caption__source" (Bild:nbsp;(c) arduino.cc) /p /figcaption /figure h3 class="subheading" id="nav_unter_der_haube_1"spanUnter der Haube/span/h3 pEine wichtige Ergänzung in diesem Zusammenhang ist, dass das Board zwei 32-Bit-ARM-Kerne integriert. Der Chip von ST Microelectronics (STM32H747XI) enthält einen mit 240 MHz getakteten Cortex-M4 und einen mit 480 MHz getakteten Cortex-M7. Zu beiden Kernen kommt zusätzlich jeweils eine Floating Point Unit (FPU) mit doppelter Präzision. Der M7 verfügt über einen L1-Cache. Das Board integriert zudem eine Memory Protection Unit und Hardware zur digitalen Signalverarbeitung./p pDurch die zwei Kerne ergibt sich die Möglichkeit, zwei Programme auf unterschiedlichen Prozessoren laufen zu lassen, zum Beispiel ein rechenintensives Hauptprogramm auf dem M7 und eine Motoransteuerung oder eine Anwendung zur Erfassung von Sensorwerten auf dem M4. Als Sprachen zur Programmierung stehen primär MicroPython sowie C/C++ zur Verfügung. Für die unabdingbare Kommunikation und Synchronisation zwischen den Programmen auf M4 und M7 existiert in der zugehörigen Arduino-Bibliothek ein entsprechender RPC-Mechanismus, der Funktionsaufrufe zwischen dem M4 und dem M7 gestattet. Das Board bietet 1 MByte Arbeitsspeicher und 2 MByte Flashspeicher, der sich in zwei Bereiche für die beiden Microcontroller partitionieren lässt. Wer nur den M7 nutzt, kann die vollen 2 MByte Flashspeicher für das dort laufende Programm nutzen. Auf dem Board befinden sich des Weiteren 8 MByte SDRAM, die Entwickler mit codeSDRAM.malloc()/code allokieren, benutzen, und danach mit codeSDRAM.free()/code freigeben können (siehe Header codeSDRAM.h/code). Über einen QSPI-Anschluss sind weitere 16 MByte externer Flashspeicher angeschlossen, die Entwickler zur Datenablage verwenden können, wobei die Firmware des Giga R1 die Dateisysteme FATFS und littleFS unterstützt. Nach den hierfür erforderlichen Konfigurationsschritten ist der Flashspeicher ebenfalls als externes USB Flash Drive nutzbar./p pGrundlage des Giga ist Mbed OS, ein quelloffenes, echtzeitbasiertes, und ressourcenschonendes Betriebssystem für IoT-Boards, das sich um Aspekte wie Konnektivität, Sicherheit, Speicher, Gerätemanagement, Supportbibliotheken und Treiber kümmert. Es integriert auch RTOS, das Mechanismen für nebenläufige Threads beisteuert./p h3 class="subheading" id="nav_noch_mehr__2"Noch mehr Tiefgang/h3 pAls Eingangsspannung erlaubt Giga zwischen 6V und 24V, während die Betriebsspannung wie bei modernen Boards 3,3V beträgt. Wer also vorhandene Schaltungsentwürfe verwendet, die sich auf den Arduino Mega (oder Uno) mit seinen 5V Betriebsspannung stützen, sollte etwas Zeit für das Redesign einplanen. In diesem Fall bietet es sich an, einen Logic Level Konverter oder einen selbst gebauten Spannungsteiler zu verwenden. Jeder digitale Port bietet mit rund 8 mA relativ wenig Energie. Als kompatible Shields gibt Arduino das aktuelle Motion-Shield, das Relay-Shield, das Ethernet-Shield und das Motorsteuerungs-Shield für den Mega an./p pZur Zusammenarbeit über USB fungieren ein USB-C und ein USB-A Anschluss. Ersterer dient der Programmierung, unterstützt HID (Human Interface Design) und versorgt das Board mit Strom, sofern keine anderen Spannungsquellen angeschlossen sind, letzterer erlaubt als USB-Host die Zusammenarbeit mit Massenspeichern oder Tastaturen./p pEin dediziertes Modul (Murata LBEE5KL1DX-883) ist für die Kommunikation über WiFi (802.11b/g/n mit 65 Mbps) und Bluetooth/BLE (Versionen 5.X und 4.2) zuständig. Dem Arduino Giga R1 liegt zu diesem Zweck eine passende, über eine Micro UFL Verbindung anschließbare Antenne bei – auf dem Board selbst ist keine Antenne integriert. Über ein entsprechendes Shield lässt sich zusätzlich huckepack ein Ethernetanschluss hinzufügen. Was Bluetooth LE betrifft, nutzen Anwendungen für Version 4.2 den zugehörigen Arduino-Stack, während der Cordio-Stack die BLE Versionen 5.X unterstützt./p pFür Bus-orientierte Kommunikation mit angeschlossener Hardware stehen vier UARTs, drei I2C-Anschlüsse, zwei SPI-Ports und eine CAN-Anbindung (über einen notwendigen externen Transceiver) zur Verfügung./p pEin ATECC608A-MAHDA-T Crypto-Modul von MICROCHIP sorgt für Sicherheitsfunktionen wie Verschlüsselung und Authentifizierung./p h3 class="subheading" id="nav_ein_und__3"Ein- und Ausgänge/h3 figure class="a-inline-image a-u-inline" div img alt class="legacy-img " decoding="async" height="637" loading="eager" src="https://heise.cloudimg.io/width/696/q85.png-lossy-85.webp-lossy-85.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/PinoutDesArduinoGiga-76417981b4e67de4.png" srcset="https://heise.cloudimg.io/width/336/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/PinoutDesArduinoGiga-76417981b4e67de4.png 336w, https://heise.cloudimg.io/width/1008/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/PinoutDesArduinoGiga-76417981b4e67de4.png 1008w, https://heise.cloudimg.io/width/1392/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/PinoutDesArduinoGiga-76417981b4e67de4.png 2x" width="696" /div figcaption class="a-caption " p class="a-caption__text" /pdiv class="text"Das Board besitzt eine enorme Fülle von Anschlüssen, sogar einen CAN-Bus-Anschluss, und lässt kaum Wünsche offen./div p class="a-caption__source" (Bild:nbsp;(c) arduino.cc) /p /figcaption /figure pAn Ein-/Ausgabe-Ports gibt es 76 digitale Pins, 12 analoge Ausgabepins sowie 12 PWM-fähige Pins, was für die meisten Anwendungen problemlos genügen sollte. Über Digital-Analog-Konverter lassen sich an zwei analogen Pins entsprechende Umwandlungen bewerkstelligen, was etwa bei der Audioausgabe notwendig ist. Da das Board wie üblich etliche Pins mit verschiedenen Funktionen belegt, sollte der Entwickler das natürlich beim Schaltungsentwurf berücksichtigen. Alle GPIO-Pins (Pins 22 bis 75) lassen sich Interrupt-gesteuert nutzen, was dem Programmierer hilft, schnell auf externe Ereignisse zu reagieren, etwa dem Anliegen eines Sensorwerts oder dem Betätigen eines Pushbutton./p pEin VRTC-Eingang erlaubt den kontinuierlichen Betrieb der Echtzeituhr, ein OFF-Pin das Ausschalten des Boards von außen. Es empfiehlt sich, nach Start des Boards die aktuelle Zeit über WiFi über einen NTP (Network Time Protocol)-Server zu beziehen und die Echtzeituhr damit zu füttern./p pDarüber hinaus integriert der Giga R1 Anschlüsse für Kameras (zum Beispiel Arducam über die Pins: I2C + D54-D67), Mikrofone beziehungsweise Audio (DAC0, DAC1, A7) und Anzeigen (über D1N, D0N, D1P, D0P, CKN, CKP + D68-D75) sowie einen JTAG-Konnektor für Debugging/Programmer-Hardware. Intern besitzt der Mikrocontroller einen 2D-Grafikbeschleuniger mit einer Auflösung von bis zu 1024x768 Bildpunkten./p pDamit eröffnet sich eine Fülle von Anwendungsgebieten. Als mögliche Anwendungen des Arduino Giga R1 beschreibt das a href="https://docs.arduino.cc/static/87ecbda44860150906c0415c27b9ccfc/ABX00063-datasheet.pdf" rel="external noopener" target="_blank"strongProduct Reference Manual [1]/strong/a zum Beispiel 3D-Drucker, Audioverarbeitungshardware, Geräte zur Datenakquisition, Signalverarbeitung sowie Robotikanwendungen./p pWer mehr a href="https://docs.arduino.cc/hardware/giga-r1-wifi" rel="external noopener" target="_blank"strongtechnische Details zum Giga R1 benötigt, kann entsprechende Dokumentation auf der Arduino-Seite [2]/strong/a finden./p pÜber den BOOT0-Knopf auf dem Board lässt sich durch Gedrückthalten beim Hochfahren des Boards ein OTA (Over the Air)-Firmware-Update auslösen. Mittels des RST-Buttons lassen sich Programme resetten (einfaches drücken) oder das Board in den Bootloader-Modus versetzen (zweifaches drücken kurz hintereinander), um das Board zu (re-)programmieren. Die rote LED blinkt 4 mal schnell und viermal langsam, sofern innerhalb der Mbed-OS-Firmware ein Fehler erkannt wurde./p h3 class="subheading" id="nav_ide_und__4"IDE und Programmierung/h3 pZum Entwickeln von Anwendungen eignen sich Arduino IDE 1.8.X sowie deren Nachfolger: die Arduino IDE 2.0.X. Alternativ lassen sich auch der Arduino Webeditor und die Arduino-IoT-Cloud verwenden. Eine passende Platform-IO- beziehungsweise Visual-Studio-Code-Anbindung gab es zum Zeitpunkt der Artikelerstellung noch nicht. Beim Einsatz von MicroPython bieten sich stattdessen die a href="https://thonny.org/" rel="external noopener" target="_blank"strongThonny IDE [3]/strong/a oder das a href="https://labs.arduino.cc/en/labs/micropython" rel="external noopener" target="_blank"strongArduino Lab für MicroPython [4]/strong/a an. Auf der Webseite zum Giga R1 steht allerdings der Hinweis, dass die Unterstützung von MicroPython momentan noch experimentell sei. Jedenfalls lässt sich ein MicroPython-Programm auf einem der beiden Kerne nutzen, während auf dem anderen C++-Code läuft. Freilich können auf beiden Kernen auch C++- oder MicroPython-Programme laufen./p pIch habe zum Test die Arduino IDE 2.0.5 verwendet. Über das Menü span class="tx_caps rte__tx--caps"Toolsgt;Manage Library/span installieren Nutzer die Unterstützung für Mbed OS Giga Boards v4.0.2 über den Boardmanager./p figure class="a-inline-image a-u-inline" div img alt class="legacy-img " decoding="async" height="379" loading="eager" src="https://heise.cloudimg.io/width/696/q85.png-lossy-85.webp-lossy-85.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/InstallierenGigaBoardManagerArduinoIDE-c7d30c70e6fbb5dd.png" srcset="https://heise.cloudimg.io/width/336/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/InstallierenGigaBoardManagerArduinoIDE-c7d30c70e6fbb5dd.png 336w, https://heise.cloudimg.io/width/1008/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/InstallierenGigaBoardManagerArduinoIDE-c7d30c70e6fbb5dd.png 1008w, https://heise.cloudimg.io/width/1392/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/InstallierenGigaBoardManagerArduinoIDE-c7d30c70e6fbb5dd.png 2x" width="696" /div figcaption class="a-caption " p class="a-caption__text" /pdiv class="text"Die Installation des Giga erfolgt in der Arduino 2.x IDE mittels des Boardmanagers/div p class="a-caption__source" (Bild:nbsp;(c) arduino.cc) /p /figcaption /figure pNach der Board-Installation können Nutzer über das span class="tx_caps rte__tx--caps"Filegt;Examples/span-Menü auf exemplarische Sketches zugreifen, entweder auf allgemeine oder spezifische für ein STM32H747_System./p figure class="a-inline-image a-u-inline" div img alt class="legacy-img " decoding="async" height="1195" loading="eager" src="https://heise.cloudimg.io/width/696/q85.png-lossy-85.webp-lossy-85.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/GigaBeispieleArduinoIDE-2367cf7a30e29487.png" srcset="https://heise.cloudimg.io/width/336/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/GigaBeispieleArduinoIDE-2367cf7a30e29487.png 336w, https://heise.cloudimg.io/width/1008/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/GigaBeispieleArduinoIDE-2367cf7a30e29487.png 1008w, https://heise.cloudimg.io/width/1392/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/GigaBeispieleArduinoIDE-2367cf7a30e29487.png 2x" width="696" /div figcaption class="a-caption " p class="a-caption__text" /pdiv class="text"Nach der Installation des Boards finden sich in der Arduino IDE einige Beispielssketche für das Arduino Giga R1 WiFi Board/div p class="a-caption__source" (Bild:nbsp;(c) arduino.cc) /p /figcaption /figure pDer IDE müssen wir noch mitteilen, wie sich der M4-Kern und der M7-Kern den Flashspeicher aufteilen sollen./p figure class="a-inline-image a-u-inline" div img alt class="legacy-img " decoding="async" height="539" loading="eager" src="https://heise.cloudimg.io/width/696/q85.png-lossy-85.webp-lossy-85.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/FestlegenSpeicheraufteilungArduinoIDE-ca33a68ae1ddc732.png" srcset="https://heise.cloudimg.io/width/336/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/FestlegenSpeicheraufteilungArduinoIDE-ca33a68ae1ddc732.png 336w, https://heise.cloudimg.io/width/1008/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/FestlegenSpeicheraufteilungArduinoIDE-ca33a68ae1ddc732.png 1008w, https://heise.cloudimg.io/width/1392/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/FestlegenSpeicheraufteilungArduinoIDE-ca33a68ae1ddc732.png 2x" width="696" /div figcaption class="a-caption " p class="a-caption__text" /pdiv class="text"In der IDE lässt sich definieren, wie sich der M7-Kern (Hauptkern) und der M4 (Koprozessorkern) den Flashsspeicher aufteilen sollen./div p class="a-caption__source" (Bild:nbsp;(c) arduino.cc) /p /figcaption /figure pUnd außerdem, auf welchen Kern die IDE den aktuellen Sketch uploaden soll./p figure class="a-inline-image a-u-inline" div img alt class="legacy-img " decoding="async" height="565" loading="eager" src="https://heise.cloudimg.io/width/696/q85.png-lossy-85.webp-lossy-85.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/FestlegenCoreArduinoIDE-6f99781a4f9e5691.png" srcset="https://heise.cloudimg.io/width/336/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/FestlegenCoreArduinoIDE-6f99781a4f9e5691.png 336w, https://heise.cloudimg.io/width/1008/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/FestlegenCoreArduinoIDE-6f99781a4f9e5691.png 1008w, https://heise.cloudimg.io/width/1392/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/FestlegenCoreArduinoIDE-6f99781a4f9e5691.png 2x" width="696" /div figcaption class="a-caption " p class="a-caption__text" /pdiv class="text"Auf welchen der beiden Kerne der aktuelle Sketch landen soll, lässt sich ebenfalls über das Tools-Menü bestimmen./div p class="a-caption__source" (Bild:nbsp;(c) arduino.cc) /p /figcaption /figure pIn der Arduino IDE findet sich im Tools-Menü nach der Installation des angeschlossenen Giga-Boards die Konfiguration./p figure class="a-inline-image a-u-inline" div img alt class="legacy-img " decoding="async" height="772" loading="eager" src="https://heise.cloudimg.io/width/638/q85.png-lossy-85.webp-lossy-85.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/KonfigGigaBoardArduinoIDE-305d1db883995578.png" srcset="https://heise.cloudimg.io/width/336/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/KonfigGigaBoardArduinoIDE-305d1db883995578.png 336w, https://heise.cloudimg.io/width/1008/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/KonfigGigaBoardArduinoIDE-305d1db883995578.png 1008w, https://heise.cloudimg.io/width/1276/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/KonfigGigaBoardArduinoIDE-305d1db883995578.png 2x" width="638" /div figcaption class="a-caption " p class="a-caption__text" /pdiv class="text"Im Tools-Menü lässt sich die aktuelle Konfiguration des Boards überprüfen./div p class="a-caption__source" (Bild:nbsp;(c) arduino.cc) /p /figcaption /figure pFür die Kommunikation zwischen beiden Kernen existiert eine RPC-Bibliothek./p figure class="a-inline-image a-u-inline" div img alt class="legacy-img " decoding="async" height="406" loading="eager" src="https://heise.cloudimg.io/width/696/q85.png-lossy-85.webp-lossy-85.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/KommunikationZwischenDenKernen-acffe0093ae0e9c3.png" srcset="https://heise.cloudimg.io/width/336/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/KommunikationZwischenDenKernen-acffe0093ae0e9c3.png 336w, https://heise.cloudimg.io/width/1008/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/KommunikationZwischenDenKernen-acffe0093ae0e9c3.png 1008w, https://heise.cloudimg.io/width/1392/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/KommunikationZwischenDenKernen-acffe0093ae0e9c3.png 2x" width="696" /div figcaption class="a-caption " p class="a-caption__text" /pdiv class="text"Eine spezielle RPC-Bibliothek erlaubt die Kommunikation zwischen beiden Kernen./div p class="a-caption__source" (Bild:nbsp;(c) arduino.cc) /p /figcaption /figure h3 class="subheading" id="nav_programmbeispiel__5"Programmbeispiel für die Kommunikation zwischen M7 und M4/h3 pUm zwischen beiden Kernen kommunizieren zu können, bedarf es entsprechender Funktionalität zwischen den Kernen. Zu beachten sind zwei Tatsachen: Der M4 kann nicht auf den seriellen Monitor schreiben. Stattdessen nutzt der Sketch des M4 die Routine codeRPC.println()/code./p pDie RPC-Bibliothek nutzt der M4-Core zur Kommunikation mit dem M7-Core:/p a-code language="c" pre class="rte__tx--listing listing"code#include lt;RPC.hgt; // Inkludieren der RPC-Bibliothek/code/pre /a-code pInitialisierung der RPC-Bibliothek:/p a-code language="clike" pre class="rte__tx--listing listing"codevoid setup() { // Einmal ausgeführt RPC.begin(); // Initialisierung }/code/pre /a-code pDas Programm auf dem M4 sendet kontinuierlich eine Zeichenkette an den Sketch im M7:/p a-code language="c" pre class="rte__tx--listing listing"codevoid loop() { // put your main code here, to run repeatedly: RPC.println("Hello World!"); // Schreiben von Info an den M7 Core } /code/pre /a-code pIm M7-Core empfangen wir die Information und schreiben sie auf den seriellen Monitor. Hier spielt die zweite Tatsache eine Rolle: Der M4 startet nicht von selbst. Das erledigt der Aufruf von codeRPC.begin()/code im M7-Kern./p pDas Programm auf dem M7 baut eine Verbindung auf dem seriellen Monitor auf, und initialisiert die Kommunikation. Zugleich dient codeRPC.begin()/code zum Booten des M4:/p a-code language="c" pre class="rte__tx--listing listing"code#include lt;RPC.hgt; void setup() { // put your setup code here, to run once: →Serial.begin(9600); // Starten der Kommunikation // mit seriellem Monitor →RPC.begin(); // Starten der gt;Kommunikation mit M4 } /code/pre /a-code pIn der Schleife werden kontinuierlich die vom M4 empfangenen Daten gelesen:/p a-code language="c" pre class="rte__tx--listing listing"codevoid loop() { String buffer = ""; // Einlesen der Nachricht vom M4 while (RPC.available()) { buffer += (char)RPC.read(); } /code/pre /a-code pAnschließend wird die empfangene Zeichenkette auf dem seriellen Monitor geschrieben:/p a-code language="c" pre class="rte__tx--listing listing"codeif (buffer.length() gt; 0) { Serial.print(buffer); // Schreiben derselben Information // zum seriellen Monitor } } /code/pre /a-code pAuf dem seriellen Monitor sehen wir nun - wenig überraschend - die folgende Ausgabe:/p figure class="a-inline-image a-u-inline" div img alt class="legacy-img " decoding="async" height="390" loading="eager" src="https://heise.cloudimg.io/width/696/q85.png-lossy-85.webp-lossy-85.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/AusgabeAmSeriellenMonitor-979ee499eb82108f.png" srcset="https://heise.cloudimg.io/width/336/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/AusgabeAmSeriellenMonitor-979ee499eb82108f.png 336w, https://heise.cloudimg.io/width/1008/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/AusgabeAmSeriellenMonitor-979ee499eb82108f.png 1008w, https://heise.cloudimg.io/width/1392/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/AusgabeAmSeriellenMonitor-979ee499eb82108f.png 2x" width="696" /div figcaption class="a-caption " p class="a-caption__text" /pdiv class="text"Der M7 startet den M4 mittels RPC.begin(). wartet auf dessen Nachricht, und gibt sie am seriellen Monitor aus./div p class="a-caption__source" (Bild:nbsp;Screenshot) /p /figcaption /figure pWir können im Sketch abfragen, ob der Sketch auf dem M4 läuft:/p a-code language="c" pre class="rte__tx--listing listing"codeif (currentCPU() == "M4") { //run M4 code } /code/pre /a-code poder auf dem M7:/p a-code language="c" pre class="rte__tx--listing listing"codeif (currentCPU() == "M7") { //run M7 code }/code/pre /a-code pZum Testen des WiFi-Moduls auf dem Giga R1 WiFi habe ich einen Beispielssketch aus span class="tx_caps rte__tx--caps"Filegt;Examples/span genutzt (WiFiWebClient (c) Tom Igoe). Das Programm verbindet sich zu einem WLAN-Netzwerk, zeigt die zugehörigen Netzwerkdaten an, nimmt Verbindung zum Server codeexample.com/code auf, und holt sich die Seite codeindex.html/code, die es dann im seriellen Monitor ausgibt./p pDas folgende Beispielsprogramm ist für den Portenta H7 geschrieben, läuft aber auch auf dem Arduino Giga R1 WiFi:/p a-code language="c" pre class="rte__tx--listing listing"code/* Web client This sketch connects to a website (http://example.com) using the WiFi module. This example is written for a network using WPA encryption. For WEP or WPA, change the Wifi.begin() call accordingly. Circuit: * Arduino Portenta H7 created 13 July 2010 by dlf (Metodo2 srl) modified 31 May 2012 by Tom Igoe */ /code/pre /a-code pWir verwenden die WiFi-Bibliothek:/p pre class="rte__tx--listing"#include lt;WiFi.hgt;/pre pZum Zugriff auf das WLAN benötigen wir SSID und Passwort. Diese sollten normalerweise in einer Headerdatei wie codearduino_secrets.h/code abgelegt sein:/p a-code language="c" pre class="rte__tx--listing listing"code#include "arduino_secrets.h" ///////please enter your sensitive data in the ///////Secret tab/arduino_secrets.h char ssid[] = "#########"; // your network SSID (name) char pass[] = "#########"; // your network password // (use for WPA, or use as key for WEP) int keyIndex = 0; // your network key Index number // (needed only for WEP)/code/pre /a-code pEs soll ein Zugriff auf den Host codeexample.com/code erfolgen:/p a-code language="c" pre class="rte__tx--listing listing"codeint status = WL_IDLE_STATUS; // if you don't want to use DNS (and reduce your sketch size) // use the numeric IP instead of the name for the server: // IPAddress server(93,184,216,34); // IP address for // example.com (no DNS) char server[] = "example.com"; // host name for example.com // (using DNS) /code/pre /a-code pDer Arduino-Sketch fungiert als Web-Client:/p pre class="rte__tx--listing"WiFiClient client;/pre pZunächst etabliert der Sketch die Verbindung zum seriellen Monitor:/p a-code language="c" pre class="rte__tx--listing listing"codevoid setup() { //Initialize serial and wait for port to open: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. // Needed for native USB port only } /code/pre /a-code p... und überprüft, ob das Board über ein WiFi-Modul verfügt:/p a-code language="c" pre class="rte__tx--listing listing"code// check for the WiFi module: if (WiFi.status() == WL_NO_SHIELD) { Serial.println("Communication with WiFi module failed!"); // don't continue while (true); } /code/pre /a-code pNun kommt es zum Verbindungsaufbau mit der angegebenen WLAN-Netzwerk-codessid/code und dem Schlüssel codepass /codeals Basis:/p a-code language="c" pre class="rte__tx--listing listing"code// attempt to connect to Wifi network: while (status != WL_CONNECTED) { Serial.print("Attempting to connect to SSID: "); Serial.println(ssid); // Connect to WPA/WPA2 network. // Change this line if using open or WEP network: status = WiFi.begin(ssid, pass); /code/pre /a-code pDrei Sekunden werden abgewartet. Im Erfolgsfall sehen wir die Ausgabe der WiFi-Client-Konfiguration:/p a-code language="c" pre class="rte__tx--listing listing"code// wait 3 seconds for connection: delay(3000); } Serial.println("Connected to wifi"); printWifiStatus(); /code/pre /a-code pAnschließend verbindet sich der Sketch mit dem gewünschten Host. Angefordert wird die Seite codeindex.html/code:/p a-code language="c" pre class="rte__tx--listing listing"codeSerial.println("\nStarting connection to server..."); // if you get a connection, report back via serial: if (client.connect(server, 80)) { Serial.println("connected to server"); // Make a HTTP request: client.println("GET /index.html HTTP/1.1"); client.print("Host: "); client.println(server); client.println("Connection: close"); client.println(); } } /code/pre /a-code pSolange Daten des Hosts anliegen, werden diese am seriellen Monitor ausgegeben:/p a-code language="c" pre class="rte__tx--listing listing"codevoid loop() { // if there are incoming bytes available // from the server, read them and print them: while (client.available()) { char c = client.read(); Serial.write(c); } /code/pre /a-code pIst die Übertragung beendet, kommt es zum Verbindungsabbau:/p a-code language="c" pre class="rte__tx--listing listing"code// if the server's disconnected, stop the client: if (!client.connected()) { Serial.println(); Serial.println("disconnecting from server."); client.stop(); /code/pre /a-code pDer Sketch endet in einer Endlosschleife:/p a-code language="c" pre class="rte__tx--listing listing"code// do nothing forevermore: while (true); } } /code/pre /a-code pDie Methode codeprintWifiStatus()/code gibt zunächst das verbundene WLAN-Netz (SSID) aus:/p a-code language="c" pre class="rte__tx--listing listing"codevoid printWifiStatus() { // print the SSID of the network you're attached to: Serial.print("SSID: "); Serial.println(WiFi.SSID()); /code/pre /a-code pDanach informiert er über die dem Board zugewiesene IP-Adresse:/p a-code language="c" pre class="rte__tx--listing listing"code// print your board's IP address: IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); /code/pre /a-code pZu guter Letzt kommt es noch zur Ausgabe der Signalstärke:/p a-code language="c" pre class="rte__tx--listing listing"code// print the received signal strength: long rssi = WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.print(rssi); Serial.println(" dBm"); } /code/pre /a-code pDie Ausgabe des obigen Programmes schaut wie folgt aus:/p figure class="a-inline-image a-u-inline" div img alt class="legacy-img " decoding="async" height="417" loading="eager" src="https://heise.cloudimg.io/width/696/q85.png-lossy-85.webp-lossy-85.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/WiFiBeispielsAusgabe-d6e0b8e62504a135.png" srcset="https://heise.cloudimg.io/width/336/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/WiFiBeispielsAusgabe-d6e0b8e62504a135.png 336w, https://heise.cloudimg.io/width/1008/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/WiFiBeispielsAusgabe-d6e0b8e62504a135.png 1008w, https://heise.cloudimg.io/width/1392/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/WiFiBeispielsAusgabe-d6e0b8e62504a135.png 2x" width="696" /div figcaption class="a-caption " p class="a-caption__text" /pdiv class="text"Diese Ausgabe erzeugt das Beispielsprogramm nach erfolgreichem Verbindungsaufbau zum lokalen WiFi-Netzwerk und der anschließenden Kommunikation mit dem Server example.com./div /figcaption /figure h3 class="subheading" id="nav_beispiel__6"Beispiel: Sensor lesen/h3 pDas nachfolgende Beispiel arbeitet wieder mit zwei Sketches. Der erste läuft unter dem M7-Core. Die Methode codeA0Lesen()/code dient dem Auslesen des Sensorwerts am analogen Port codeA0/code. Dazu bindet und registriert der Code die Methode unter dem Namen codeA0Lesen/code als über RPC aufrufbare Methode. In codeloop()/code empfängt der M7 alle Meldungen des M4 und gibt sie anschließend auf dem seriellen Monitor aus. Wie bereits erwähnt kann Code auf dem M4 nicht auf den seriellen Monitor zugreifen, sondern muss dazu den Umweg über den M7 nutzen:/p a-code language="c" pre class="rte__tx--listing listing"code// Demo-Code für den M7-Core #include "Arduino.h" #include "RPC.h" void setup() { RPC.begin(); Serial.begin(115200); // Binden/Registrieren der Methode A0Lesen() RPC.bind("A0Lesen", A0Lesen); } void loop() { // Alles einlesen, was vom M4 kommt String buffer = ""; while (RPC.available()) { buffer += (char)RPC.read(); // Buffer auffuellen } if (buffer.length() gt; 0) { Serial.print(buffer); // und ausgeben } } /* Hier wird der aktuelle Wert vom analogen Eingang A0 gelesen und zurueckgeliefert */ int A0Lesen() { int result = analogRead(A0); return result; } /code/pre /a-code pIm M4-Core nutzen wir einen eigenen Thread codesensorThread/code, der die Methode codesensor_lesen()/code ausführt. Dieser ruft jede Sekunde die RPC-Methode codeA0Lesen()/code auf, um den aktuellen Sensorwert zu erfassen. Dann sendet er übercode RPC.println()/code eine Nachricht an den M7, die dieser am seriellen Monitor ausgibt./p pspanDemo-Code für den M4-Core:/span/p a-code language="c" pre class="rte__tx--listing listing"code#include "Arduino.h" #include "RPC.h" using namespace rtos; Thread sensorThread; void setup() { RPC.begin(); Serial.begin(115200); /* Starte neuen Thread, der die Funktion sensor_lesen ausfuehrt */ sensorThread.start(sensor_lesen); } void loop() { } // Code für den Thread void sensor_lesen() { while (true) { delay(1000); // 1 Sekunde warten // Aufruf der Funktion A0Lesen im M7 auto result = RPC.call("A0Lesen").aslt;intgt;(); RPC.println("Result is " + String(result)); } } /code/pre /a-code pAm seriellen Monitor sehen wir dann eine Ausgabe wie die folgende:/p figure class="a-inline-image a-u-inline" div img alt class="legacy-img " decoding="async" height="322" loading="eager" src="https://heise.cloudimg.io/width/300/q85.png-lossy-85.webp-lossy-85.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/SeriellerMonitorA0Lesen-7071080309fa75f1.png" srcset="https://heise.cloudimg.io/width/336/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/SeriellerMonitorA0Lesen-7071080309fa75f1.png 336w, https://heise.cloudimg.io/width/1008/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/SeriellerMonitorA0Lesen-7071080309fa75f1.png 1008w, https://heise.cloudimg.io/width/600/q70.png-lossy-70.webp-lossy-70.foil1/_www-heise-de_/imgs/18/4/0/7/4/3/5/7/SeriellerMonitorA0Lesen-7071080309fa75f1.png 2x" width="300" /div figcaption class="a-caption " p class="a-caption__text" /pdiv class="text"Der Sketch auf dem M4-Core schickt Meldungen an den M7-Core, die dieser am seriellen Monitor ausgibt./div /figcaption /figure h3 class="subheading" id="nav_alles_gut_oder__7"spanAlles gut oder was?/span/h3 pMomentan lässt die Zahl der für den Giga verfügbaren Software wie etwa Treiber und Bibliotheken noch viel Luft nach oben. Das ist allerdings der Tatsache geschuldet, dass naturgemäß in einem so frühen Stadium noch nicht viel davon existieren kann. Ein Ökosystem muss sich erst entwickeln. Der Preis erscheint etwas hoch. Dem ist allerdings entgegenzusetzen, dass sich das Giga R1 Board leistungstechnisch eher auf den Höhen der Potenta-Boards, speziell dem Portenta H7 Lite bewegt und eine hervorragende Plattform für Edge-Anwendungen wie KI bietet. Wer also lediglich ein Board für kleinere beziehungsweise weniger anspruchsvolle Problemstellungen sucht, ist mit anderen preisgünstigeren Arduino Boards, ESP32-Boards oder dem Raspberry Pi Pico W besser bedient./p pWas die Kommunikation mit der Außenwelt betrifft, lässt das Giga-Board kaum Wünsche offen. Das gilt sowohl für Kommunikation mit anderer Software via WiFi und Bluetooth als auch für die systemnahe Kommunikation mit Peripherie. Die Zahl der verfügbaren Schnittstellen ist üppig./p pDas Konzept der zwei Microcontroller und der anderen Schnittstellen entspringt der Portenta-Familie und hat deutliche Vorteile bei der Implementierung leistungshungiger Embedded Systeme. Die Positionierung des Giga R1 als Highend-Board zwischen den industriellen Arduino-Produkten und Arduino-Boards für größere Maker-Projekte ist daher sicher gerechtfertigt./p pDas soll es im Wesentlichen zu den Leitungsdetails des Arduino Giga R1 WiFi gewesen sein. In zukünftigen Folgen sprechen wir über konkrete Anwendungen. !-- RSPEAK_STOP -- !-- RSPEAK_START -- /p hr p strongURL dieses Artikels:/strongbr smallcodehttps://www.heise.de/-8039111/code/small /p p strongLinks in diesem Artikel:/strongbr smallcodestrong[1]/strongnbsp;https://docs.arduino.cc/static/87ecbda44860150906c0415c27b9ccfc/ABX00063-datasheet.pdf/code/smallbr smallcodestrong[2]/strongnbsp;https://docs.arduino.cc/hardware/giga-r1-wifi/code/smallbr smallcodestrong[3]/strongnbsp;https://thonny.org//code/smallbr smallcodestrong[4]/strongnbsp;https://labs.arduino.cc/en/labs/micropython/code/smallbr smallcodestrong[5]/strongnbsp;mailto:michael.stal@gmail.com/code/smallbr /p p class="printversion__copyright" emCopyright © 2023 Heise Medien/em /p pstronga href="https://blockads.fivefilters.org"Adblock test/a/strong a href="https://blockads.fivefilters.org/acceptable.html"(Why?)/a/p
  • 14. April 2023 um 13:13

Der Pragmatische Architekt: Blogthemen der nächsten Zeit

Von heise online
!-- RSPEAK_STOP -- figure class="aufmacherbild" img src="https://heise.cloudimg.io/width/700/q75.png-lossy-75.webp-lossy-75.foil1/_www-heise-de_/imgs/18/3/7/1/9/3/6/8/E3E06860-BCB0-4FB1-99C8-D295DC7CE6BE-f37f434962090a2f.jpeg" srcset="https://heise.cloudimg.io/width/540/q75.png-lossy-75.webp-lossy-75.foil1/_www-heise-de_/imgs/18/3/7/1/9/3/6/8/E3E06860-BCB0-4FB1-99C8-D295DC7CE6BE-f37f434962090a2f.jpeg 540w" sizes="(min-width: 80em) 43.75em, (min-width: 64em) 66.66vw, 100vw" alt class="img-responsive" figcaption class="akwa-caption" p class="caption akwa-caption__text"Das Arduino Giga R1 Board ist Theme einer baldigen Folge/p /figcaption /figure !-- RSPEAK_START -- p strongIn der nächsten Zeit bekommt dieser Blog einen Reboot. Bei den Themen gibt es eine Mischung aus Embedded Boards, Softwarearchitektur und KI. /strong /p pNach einer Pause von neun Monaten werde ich den Blog "Der Pragmatische Architekt" rebooten. Welche Themen zur Sprache kommen, beschreibt der vorliegende Beitrag./p pDieser Blog war aus zeitlichen Gründen in den letzten Monaten verwaist. Es ist an der Zeit, ihn wieder mit Leben zu füllen. In zukünftigen Folgen sollen weiterhin Embedded Boards eine wichtige Rolle spielen. Zwischendrin geht es aber auch um weitere IT-Themen wie Softwarearchitektur und KI./p pGeplant sind unter anderem Posts zu:/p ul class="rte__list rte__list--unordered"liArduino Giga R1 WiFi/liliOszilloskop Korg NTS-2 zur Analyse von Audiosignalen/liliRaspberry Pi Pico W/liliRaspberry Pi Zero (2)/lilidas unvermeidliche Thema ChatGPT/liliDirekter Zugriff auf Sensorik über PCs/li/ul pNatürlich liegt es dem Autor am Herzen, Themen zu adressieren, die Leserinnen und Leser interessieren. Gerne nehme ich zudem Anregungen in Kommentaren zu diesem Beitrag entgegen, wenn, wenn jemand ein spannendes Thema vermisst, geben Sie es gerne in den Kommentaren an. Ich freue mich jedenfalls, wieder aktiv sein zu können./p p !-- RSPEAK_STOP -- !-- RSPEAK_START -- /p hr p strongURL dieses Artikels:/strongbr smallcodehttps://www.heise.de/-7548368/code/small /p p strongLinks in diesem Artikel:/strongbr smallcodestrong[1]/strongnbsp;mailto:rme@ix.de/code/smallbr /p p class="printversion__copyright" emCopyright © 2023 Heise Medien/em /p pstronga href="https://blockads.fivefilters.org"Adblock test/a/strong a href="https://blockads.fivefilters.org/acceptable.html"(Why?)/a/p
  • 29. März 2023 um 11:22

Moog Mavis – ein monophoner und semimodularer Selbstbau-Synthesizer

Von heise online

Moog Mavis (c) Moog

Das Moog Mavis Selbstbaukit eignet sich gut als Einstieg in Synthesizer, nicht nur weil es East-Coast-Synthese mit West-Coast-Synthese verknüpft.

Jüngster Spross in der Produktpalette des traditionsreichen Synthesizer-Spezialisten Moog ist der analoge, monophone Synthesizer Mavis. Er basiert auf den klassischen analogen Moog-Schaltungen (sogenannte East-Coast-Synthese) und unterstützt zusätzlich Wavefolding aus der West-Coast-Synthese. (Wer sich für nähere Details interessiert, findet im Artikel über das ZeKit [1] eine Textbox, die wichtige Eigenschaften der verbreitesten Synthese-Stile beschreibt).

Das Schöne am Mavis ist dabei die Möglichkeit, eigene Signalwege zu kreieren. Dazu gibt es ein Patch-Bay, das erlaubt, viele Konfigurationen mit Hilfe von Patchkabeln zu definieren, womit Mavis einen semimodularen Ansatz bietet. Zudem dienen einige der Patchpunkte zum Anschluss externer Geräte wie einem Midi-Keyboard. oder anderen Synthesizern. Das geschieht allerdings über CV/GATE-Anschlüsse statt über Midi-Ports. Wer Mavis über ein reines MIDI-Gerät steuern will, benötigt demzufolge ein MIDI-to-CV-Interface. Siehe dazu den den Artikel auf bonedo.de [2]. Zum Glück verfügen selbst einige preisgünstige MIDI-Keyboards wie Arturia KeyStep sowohl über MIDI als auch über CV/GATE.

Preisfrage

Im Prinzip stellt Mavis den würdigen und leistungsfähigeren Nachfolger von Moogs Werkstatt-01 dar (zum Artikel über Moog Werkstatt-01 [3]). Der Synthesizer lässt sich als alleinstehende Komponente nutzen, sieht aber auch den Einbau in ein Eurorack vor.

Das Produkt ist mit einem Preis von 399 Euro allerdings das Gegenteil von einem Schnäppchen, zumal in dieser Preiskategorie auch Synthesizer wie der Arturia Microfreak oder die Volca-Produktfamilie von Korg fallen, die teilweise mehr Funktionen zu einem günstigeren Preis offerieren. Auch ist für mein Gefühl der Preisunterschied zu anderen Moog-Produkten wie Mother-32, DFAM oder Subharmonicon zu gering.

Aber für Moog-Synthesizer sind nun mal auch Moog-Preise fällig. Abgesehen davon bietet Mavis viele Features fürs Experimentieren und Lernen. Die große Moog-Community ist ebenfalls von Vorteil, da sie zahlreiche Tipps und Informationen bereitstellt. Nicht zu vergessen der unverwechselbare Klang eines Moog-Synthesizers.

Bauarbeiten

Mit einem Selbstbausynthesizer verbinden Benutzer komplizierte Lötarbeiten an der Hauptplatine, was aber in diesem Fall nicht zutrifft. Beim Zusammenbau ist lediglich das Montieren von 9 Schrauben und 24 Muttern notwendig, um nach geschätzt 15 Minuten den fertigen Synthesizer in Betrieb nehmen zu können. Das zugehörige 12V-Netzteil ist übrigens im Lieferumfang vorhanden. Ein Batteriebetrieb ist nicht vorgesehen.

Im jungfräulichen Zustand besteht Mavis aus diversen Einzelteilen.

Eine große Herausforderung ist die Montage also nicht und stellt selbst ungeschickte Zeitgenossen nicht auf die Probe.

Zunächst gilt es, das PCB an die Kopfplatte zu schrauben

Danach schraubt man zuerst Kopfplatte mit der Platine ins Gehäuse und verschraubt die Klinkenbuchsen. Dafür liefert Moog ein Werkzeug mit.

Bedienung von Mavis

Nach 15 Minuten Montage ist Mavis einsatzbereit.

Jeder Topf braucht einen Deckel

Die Bedienelemente des Mavis sind in verschiedene Bereiche unterteilt:

VCO (Voltage-Controlled Oscillator) ist die Komponente, die das Ausgangssignal beziehungsweise die gewünschte Wellenform erzeugt. Dabei ist die Auswahl von Sägezahn- und Rechteckswellen vorgesehen. Beide Wellenformen lassen sich durch den Drehknopf VCO WAVE fließend ineinander verschmelzen. Für Rechteckswellen können Musiker mittels PULSE WIDTH einstellen, wie lange sich das Signal auf Level HIGH oder Level LOW befinden soll. Zwei Modulationsquellen, entweder der Hüllkurvengenerator (EG = Envelope Generator) oder der LFO (Low Frequency Oscillator), erlauben Tonhöhe und Pulsweite dynamisch zu verändern. Dazu später mehr. Das funktioniert in etwa so, als würde man die entsprechenden Drehpotis periodisch hin- und herdrehen. Wir haben es also mit einer Form von Automatisierung zu tun. Die Knöpfe PITCH MOD AMT und PWT AMT steuern dabei wie stark die entsprechende Modulation von Tonhöhe oder Pulsweite sein soll.

VCF (Voltage-Controlled Filter) dient zum subtraktiven Formen des VCO-Signals. So ist die Frequenz einstellbar, ab der das Audiosignal gekappt werden soll (CUTOFF). RESONANCE nimmt einen Teil des so erzeugten Audiosignals und dirigiert diesen Teil erneut zum Filter um. Dadurch kann es sogar zur Oszillation des Filters kommen. Wie der VCO enthält auch der VCF den Hüllkurvengenerator (EG) und den LFO als zwei potenzielle Modulationsquellen, um die CUTOFF-Frequenz dynamisch zu variieren. Mittels des Drehknopfes VCO MOD MIX ist eine Kombination aus beiden Modulationsquellen einstellbar, während VCF MOD MIX bestimmt, wie stark die Modulation des Cutoff-Parameters sein soll.

Der VCA (Voltage-Controlled-Amplifier) ist der dritte im Bunde, was den grundsätzlichen Signalpfad betrifft. Wie nicht anders zu erwarten, kontrolliert diese Komponente über VOLUME die Lautstärke, die entweder konstant bleibt oder sich über den Hüllkurvengenerator dynamisch verändern kann. Das resultierende Ausgangssignal liegt dann am Kopfhörerausgang an. Der Schalter VCA MODE definiert, ob ein konstantes Ausgangssignal anliegen soll (Position: ON) oder der Hüllkurvengenerator die Ausgangslautstärke beeinflusst (Position: EG).

Der LFO (Low-Frequency Modulator) ist, wie bereits erwähnt, eine der beiden möglichen Modulationsquellen. Einstellbar sind die Frequenz des LFO über LFO RATE und die dafür verwendete Wellenform über LFO WAVE. Möglich sind hier Dreieckswellen oder Rechteckswellen.

Ein Hüllkurvengenerator EG bestimmt, was hinsichtlich des Signalverlaufs im Detail passieren soll, sobald der Anwender eine Taste des Keyboards drückt.

  • ATTACK definiert die Zeit bis das Audiosignal seine höchste Intensität erreicht.
  • DECAY konfiguriert, wie lange es dauert bis der Pegel erreicht ist,
  • den der Musiker über das SUSTAIN-Poti eingestellt hat.
  • Last but not least, gibt RELEASE die Zeit vor bis das Signal wieder auf 0-Pegel fällt.

Es handelt sich entsprechend um eine ADSR-Hüllkurve.

Im Bereich KEYBOARD des Mavis befinden sich 13 Tasten von Note C bis Note C1. Beim gleichzeitigen Drücken zweier Tasten gibt Mavis der niedrigeren Note Vorrang, da es sich um einen monophonen Synthesizer handelt. Mehr als ein erzeugter Ton gleichzeitig ist nicht.

  • Der Drehknopf GLIDE bestimmt wie fließend oder abrupt der Übergang zwischen zwei gespielten Tasten sein soll, was in den Extremen also an Stakkato und Legato erinnert.
  • Mit dem Drehknopf KB SCALE hat es folgendes auf sich. In linker Position umfassen alle Tasten eine einzelne Oktave mit der üblichen Skalierung von 1V pro Oktave. Dreht man den Knopf nach rechts, wird diese Skalierung vergrößert, sodass sich auf dem KEYBOARD ein breiterer Bereich von Noten und damit nichtraditionelle Skalen spielen lassen. Das Keyboard ist so umkonfigurierbar, dass der Anwender auch andere Parameter als die Tonhöhe manipulieren kann.

UTL (Utilities) erlaubt die Parametrisierung bestimmter Funktionen, die nur im Patch-Bay verfügbar sind. Das geschieht durch Anschluss von Kabeln. Der Drehknopf FOLD steuert das Wavefolding und ermöglicht dem Musiker, der vom Oszillator erzeugten Wellenform weitere Obertöne hinzuzufügen. Das funktioniert freilich nur, wenn der Musiker ein entsprechendes Signal an FOLD IN anschließt. Mittels ONE LVL lassen sich Eigenschaften wie etwa die Signalstärke des am Eingangsanschluss ONE(-5) anliegenden Audiosignals reduzieren beziehungsweise variieren. ATTENUATOR leistet dasselbe für Audiosignale, die am ATTN(+5) Eingangsport eingespeist werden.

Das Patch-Bay

In der Lieferung von Mavis befinden sich 5 Patchkabel (3,5mm-Miniklinkenstecker) und 5 beispielhafte Patchschablonen zum Auflegen auf das Bedienfeld. Die Schablonen zeigen an, welche Schalterstellungen der Benutzer für den jeweiligen Patch wie stellen soll, und welche Patchverbindungen notwendig sind. Auf diese Weise erhält der Musiker schon mal eine Grundlage für eigene Experimente.

Patchschablonen legt man über die Kopfplatte und sieht danach, welche Schritte der Patch auf dem Patchbay und den übrigen Reglern bzw. Schaltern benötigt.

Insgesamt befinden sich 24 Buchsen auf dem Patch-Bay, wovon 13 als Inputs und 11 als Outputs dienen. Die Inputs sind jeweils mit Standardtext betitelt (weißer Text auf schwarzem Hintergrund), während die Outputs in umgekehrter Darstellung (schwarzer Text auf weissem Hintergrund) notiert sind. Ohne veränderte Signalwege durch einen Patch lösen die Tasten des Keyboards sowohl den VCO als auch den EG aus, von wo die erzeugte Wellenform zum nachfolgenden VCF gelangt. Das Ausgangssignal des VCO leitet der Synthesizer wiederum zum VCA weiter. Dessen Signal gelangt zur Kopfhörerbuchse.

Es ist natürlich müßig, etliche Ein- und Ausgänge des Patch-Bay im Detail zu beschreiben. Daher sollen hier nur ein paar Beispiele adressiert werden:

  • Über die Buchse KB CV ist das von einer Taste abgehende Ausgangssignal abgreifbar.
  • Audiosignale, die zum Eingang FOLD IN gelangen, unterliegen einem Wavefolding. Das heißt übrigens auch, dass Musiker ein beliebiges Signal, etwa das eines weiteren Synthesizers, in FOLD-IN einspeisen können, um ein Wavefolding durchzuführen.
  • Die Buchsen MULT (Eingang) sowie MULT1, MULT2 (Ausgänge) helfen, ein Eingangssignal in zwei Ausgaberichtungen zu verteilen, fungieren also gewissermaßen als Y-Kabel.
  • Der interne Mixer des Mavis gibt sein Ausgangssignal auf ONE+TWO aus. Als Eingänge fungieren ONE bzw ONE(-5) sowie TWO. Während die Regelung des Eingangs ONE bzw. ONE(-5) über das Drehpoti ONE LVL erfolgt, gelangt das Signal an TWO unverändert zum Ausgang ONE+TWO. Das -5 in ONE(-5) bedeutet, dass der Anwender über den Drehknopf ONE LVL eine Offsetspannung von 0 bis -5V zum Eingangssignal von TWO addieren kann.

Auf der Mavis-Webseite [4] findet sich ein Mavis-Handbuch, ein Manual über Patches und weitere exemplarische Patchschablonen sowie ein leeres Patchsheet zum Ausdrucken. Darüber hinaus haben Anwender auf dem Internet eigene Patches hochgeladen, ebenso wie es dort YouTube-Videos über Patches, diverse Meinungen zu Mavis, sowie empfohlene Workflows gibt. Besonders interessant ist übrigens die Webseite patchstorage [5], weil sie zahlreiche Patches für Mavis zum Herunterladen anbietet.

Fazit

Moogs neuester Synthesizer Mavis kann mit seinem semimodularen Ansatz überzeugen, da er viele Möglichkeiten eröffnet. Er eignet sich sowohl für Anfänger, die das Synthesizer-Feeling erleben wollen, ohne von Dutzenden Funktionen erschlagen zu werden, als auch für Profis, die Mavis als zusätzliche Komponente in ihrer Studiokonfiguration vorsehen. Für alle, die schon einen Moog-Synthesizer des Typs Mother-32, DFAM oder Subharmonicon ihr eigen nennen, dürfte Mavis jedenfalls eine gute Ergänzung darstellen.

Mit seinem minimalistischen Ansatz erleichtert Mavis den Einstieg in die Welt der Synthesizer, bietet aber immer noch ein schier unendliches Spektrum an Patchmöglichkeiten. Der Preis ist zwar aus Moog-Sicht nachvollziehbar, aber aus meiner Sicht hätte ein Verkaufspreis von unter 300 Euro mehr Sinn gemacht. Viele potenzielle Käufer dürften nicht so tief in die Tasche greifen wollen. Trotzdem ist Mavis aus meiner subjektiven Sicht ein guter Kauf, da der Synthesizer volle Moog-Funktionalität besitzt, schon jetzt eine hilfreiche Community bietet, und East-Coast-Synthese mit West-Coast-Synthese verbindet. Wenn ich zwei Wünsche frei hätte, würde ich mich über einen integrierten Sequencer und auch über die Unterstützung von MIDI freuen.

Wer sich noch nicht sicher ist und trotzdem preisgünstig mit (semi-)modularen Synthesizern von Moog experimentieren möchte, sei auf die diversen Apps und Plugins verwiesen, die virtuelle Moog-Synthesizer wie das Moog Modell 15 virtualisieren. Zusätzlich bietet Behringer Hardware-Synthesizer zu günstigen Preisen an, die ihren Moog-Pendants klanglich und funktional sehr nahe kommen. Ein Beispiel ist das Behringer Model D zu einem Straßenpreis von 298 Euro. Diese Lösungen bieten aber kein Wavefolding.

Es gibt also immer verschiedene Wege nach Moog.

Referenzen


URL dieses Artikels:
https://www.heise.de/-7160932

Links in diesem Artikel:
[1] https://www.heise.de/blog/Fred-s-Lab-ZeKit-Synthesizer-mit-DiY-Feeling-7154810.html
[2] https://www.bonedo.de/artikel/die-besten-midi-to-cv-interfaces/
[3] https://www.heise.de/blog/Frisch-aus-der-Werkstatt-Ein-Selbstbau-Synthesizer-von-Moog-6664968.html
[4] https://www.moogmusic.com/exploremavis
[5] https://patchstorage.com/moog-mavis/
[6] https://www.moogmusic.com/exploremavis
[7] https://back.moogmusic.com/sites/default/files/2022-06/MAVIS_MANUAL_V2_06.27.2022.pdf
[8] https://back.moogmusic.com/sites/default/files/2022-06/Mavis-Patching-With-Intention_Web.pdf
[9] https://back.moogmusic.com/sites/default/files/2022-06/Mavis_Exploration_Patchbook_Web.pdf
[10] https://back.moogmusic.com/sites/default/files/2022-06/Mavis_Patchbook_Lisa_Bella_Donna.pdf
[11] https://back.moogmusic.com/sites/default/files/2022-06/Mavis_Blank_Template.pdf
[12] mailto:rme@ix.de

Copyright © 2022 Heise Medien

Adblock test (Why?)

  • 25. Juli 2022 um 10:13

Fred’s Lab ZeKit - Synthesizer mit DiY-Feeling

Von heise online
Fred’s Lab ZeKit

(c) Fred’s Lab, ZeKit

Dieser Beitrag über Synthesizer behandelt das Selbstbaukit ZeKit. Zur Sprache kommen Montage und Nutzung des vierstimmigen paraphonischen Hybrid-Synthesizers.

Die Kreationen von Fred’s Lab zeichnen sich durch kreative Namen aus, etwa Töörö, Buzzy! oder eben ZeKit. Die Hardware kommt nicht im sonst typischen Schwarz- oder Weiss-Gewand zu den Nutzern, sondern im erfrischenden Bunt. Dadurch hebt sich Fred’s Lab angenehm hervor, ohne dass die Produkte verspielt wirken. Hinter dem ungewöhnlichen Firmennamen verbirgt sich übrigens Frédéric Meslin, ein Zeitgenosse aus französischer Produktion, der in Deutschland lebt und seit 2016 kleine innovative Synthesizer erfindet und vertreibt. Fred war bis Firmengründung bei bekannten Unternehmen wie Arturia (MiniBrute-Synthesizer) und Waldorf (NW1-Synthesizer) in der Hardware-/ Softwarentwicklung beschäftigt. Diese Erfahrung macht sich bei seinen Geräten bezahlt.

Philosophie von Freds Unternehmens ist die Bereitstellung portabler Synthesizer, die ihre Besitzer beispielsweise über eine DAW (Digital Audio Workstation) á la Logix Pro X , Cubase, Ableton Live und Bitwig ansteuern. Alternativ können Musiker dafür auch jedes Midi-Gerät, egal ob Hardwaresequenzer, Midi-Keyboard oder Hardware-DAW nutzen.

Interessant ist für den vorliegenden Blog insbesondere der Bausatz ZeKit, da Fred sowohl dessen Software als auch dessen Hardware über eine Open-Source-Lizenz zur Verfügung stellt. Maker können dementsprechend die Firmware anpassen beziehungsweise erweitern, und natürlich ebenso die Hardware nach ihren Vorstellungen modifizieren. Grund genug also, das ZeKit hier zu adressieren.

Unter der Motorhaube des ZeKit

Auch wenn das ZeKit bei einigen Musikshops wegen der verwendeten digitalen Wellenerzeugung als digitaler Synthesizer firmiert, ist es genau genommen ein Hybrid, da andere Teile wie die Envelop-Generatoren, der Verstärker VCA (Voltage-Controlled Amplifier), oder der Filter VCF (= Voltage-Controlled Filter) analog vorliegen.

Der Synthesizer ist im Prinzip polyphon, das heißt bis zu vier Stimmen können gleichzeitig erklingen. Da sich aber alle Stimmen Komponenten wie den VCF und die Hüllkurvengenerator teilen, gilt ZeKit als paraphoner Synthesizer. Die Synthese der digital erzeugten Wellenformen erfolgt als Kombination von Sägezahnkurven. Generieren lassen sich in diesem Zusammenhang je 8 einstellbare monophone & paraphone Wellenformen. ZeKit integriert einen Sequenzer mit 96 Steps und 4 Noten per Step. Benutzer können zudem bis zu 16 Patterns definieren.

Wer einen Vorgeschmack auf die Möglichkeiten des ZeKit bekommen will, besucht am besten die Produktseite [5], auf der sich einige Klangbeispiele finden.

Als Schnittstellen offeriert ZeKit einen Midi-Eingang, der beispielsweise den Anschluss eines Midi-Keyboards oder eines Sequenzers erlaubt. Andere Tonquellen sind über einen Audioeingang anschließbar. An einen Audioausgang können Anwender Kopfhörer, Lautsprecher oder weiteres Equipment verbinden, um das vom ZeKit generierte Audiosignal zu verarbeiten. Ein Clock-Eingang erlaubt die Synchronisation des ZeKit mit anderen Geräten.

Herz des ZeKit ist ein 16-bit-Prozessor der Microchip-Produktfamilie PIC24F. Der Mikrocontroller läuft mit 16 MHz. Die PIC24F-Produktfamilie implementiert diverse Anschlussmöglichkeiten wie USB, SPI, UART, I2C, PWMs (Pulse-Width Modulators) und Timer, zudem ADCs (Analog-Digital Converter) und DACs (Digital-Analog Converter). Über I2S lassen sich zwischen dem Mikrocontroller und anderen Komponenten Audiodaten übertragen. Das F in PIC24F steht dafür, dass die Mikrocontroller dieser Familie Flashspeicher integrieren. Programmierbar sind die PIC-Mikrocontroller entweder mit C oder Basic. Microchip stellt für die Programmierung eine integrierte Umgebung namens MPLAB X [6] für Windows, macOS und Linux bereit, die auf einer Java-Runtime beruht.

Montage

Interessierte können den ZeKit-Synthesizer zwar auch fertig montiert für 189 Euro erwerben, aber mehr Spaß und Einblicke in das Innenleben eines Synthesizers bietet das Selbstbaukit für preisgünstige 139 Euro. Letzteres lag mir – Fred sei dank – zum Test vor. Zur Stromversorgung benötigt der ZeKit-Anwender noch ein Netzteil, das 5 bis 9 Volt Versorgungsspannung liefert.

Abgebildet sind hier alle benötigten Komponenten zum Zusammenbau des ZeKit.

Zwar ist die Montage des ZeKit mit moderater Lötarbeit verbunden, aber das ist selbst für Maker machbar, die keine Lötvirtuosen sind, da sich alle SMD-Komponenten bereits vormontiert auf der Platine des Synthesizers befinden. Zu verlöten sind lediglich passive Teile mit Through-Hole-Bauform wie Kondensatoren, Potentiometer, IC-Sockel, oder LEDs, was aber in dem beiliegenden Handbuch gut beschrieben ist. Insbesondere bei den wenigen Bauteilen, bei denen es auf die richtige Polarität ankommt – beim ZeKit sind das LEDs und Schalter mit LEDs – sollten Maker etwas mehr Sorgfalt walten lassen. Der Rest ist fast ein Kinderspiel. Im Handbuch gibt es sogar Passagen für weniger elektronikaffine Zeitgenossen, um das richtige Löten zu illustrieren. Unerfahrene sollten rund 1,5 bis 2,5 Stunden Zeitaufwand einkalkulieren, Erfahrene etwa eine Stunde.

Nun ist es an der Zeit, die Lötstation anzufeuern.

Schritt für Schritt

Gehen wir die einzelnen Schritte des Zusammenbaus durch, um aus den Bauteilen einen betriebsbereiten Synthesizer zu schaffen.

Zuvor aber ein paar Hinweise:

Hinweis 1: Klebeband ist hilfreich, um Teile auf dem Board in Position zu halten, während wir deren Beinchen auf die Platine löten.

Hinweis 2: Nach dem Löten sollten Maker die überstehenden Beinchen der Komponenten mit einem kleinen Seiten- oder besser mit einem Mittenschneider entfernen.

Hinweis 3: Wie immer empfiehlt sich das Anbringen eines antielektrostatischen Bandes ans Handgelenk. Sicher ist sicher.

Teil I der Montage: Verlöten aller Bauteile auf der Vorderseite des Boards.

Im ersten Schritt bringen wir die Sockel für die ICs auf die Hauptplatine. Das Board symbolisiert den Platz für IC-Sockel mit einer an der Spitze halbkreisförmigen Aussparung. Da die IC-Sockel und die ICs ebenfalls eine solche Aussparung besitzen, kann es nur bei grober Unachtsamkeit zu Fehlern kommen.

Zuerst werden die IC-Sockel unter Beachtung der richtigen Orientierung eingelötet.

Schritt 2 besteht darin, die blauen Filmkondensatoren (C15, C19, C21) auf das Board zu löten. Dieser Typ von Kondensator ist nicht polarisiert und kann daher in jeder Orientierung eingebaut werden. Allerdings sind die Bauelemente hitzeempfindlich. Wir sollten die Bausteine deshalb nicht länger als 5 Sekunden der Hitze des Lötkolbens aussetzen.

Anlöten der Filmkondensatoren.

Schritt 3 beinhaltet das Löten der Schalter mit roter LED (SW5, SW6, SW7, SW8, SW2, SW3, SW4). Diese Schalter arbeiten in ihrer Funktion als Schalter natürlich in jeder Orientierung. Allerdings gilt das nicht für die eingebaute rote LED. Zum Glück ist auf dem Board ein Loch mit der Markierung “R” angebracht, ebenso wie eines der sechs Schalterbeinchen eine rote Markierung besitzt. Aus diesen Markierungen geht die Positionierung der Schalter eindeutig hervor.

Nach dem Anlöten der roten LED-Schalter.

Schritt 4: Die Kippschalter, die zwei stabile Einrastpositionen besitzen, lassen sich nun in beliebiger Orientierung einbauen.

Im Schritt 5 erfolgt das Löten der beiden Arten bereitgestellter Potentiometer. Die einen besitzen auf der Unterseite die Kennung “b103”, die anderen “b104”. Diese Zahlen definieren den Widerstandswert. Zum Beispiel bedeutet die Zahl 104 einen Widerstand von 10 * 10^4 KOhm = 100 KOhm, während 103 für 10 * 10^3 KOhm = 10 KOhm steht. Die Positionen dieser Widerstände sind eindeutig auf dem Board markiert.

Schlussendlich löten wir im Schritt 6 die rote LED (fungiert als Power-Anzeige) ein. Das längere Beinchen ist der Pluspol, das kürzere der Erdungspol. Das längere Beinchen muss näher am Berührungsschalter SW2 positioniert sein als das kürzere.

Teil II der Montage: Verlöten aller Bauteile auf der Rückseite des Boards.

Im achten Schritt löten wir alle verbleibenden Bauteile auf der Boardrückseite ein, also den blauen Trimmer, die Verbindungsstecker für Audio-In, Audio-Out, Netzteil, fünfpoligen Midi-Eingang sowie die schwarze Ein-/Austaste.

Nach dem Einbau der diversen Buchsen lääst sich das ZeKit mit der Außenwelt verbinden.

Im neunten Schritt stecken wir die ICs vorsichtig in die vorgesehenen Sockel. Auch hier gilt: Zur richtigen IC-Orientierung halbkreisförmige Aussparung am IC und Sockel beachten.

Es ist vollbracht!
Teil III der Montage: Endfertigung

Im zehnten Schritt falten wir die beiliegenden Gehäuseteile zu einem Quader und montieren das Board mit vier Abstandhaltern ins Gehäuse, was nach kurzer Zeit erledigt ist. Das gilt auch für das Aufsetzen der Drehknöpfe auf die Potentiometer. Das Alublech lässt sich mit den Händen falten oder mit einer Zange und einem kleinen Schutztuch, um Kratzer zu vermeiden.

Das Board wird ins Gehäuse eingeschraubt.

Schritt 11 inkludiert jetzt nur noch das Anbringen der klebbaren Kunststofffüßchen auf der Geräteunterseite. Damit ist der Zusammenbau beendet.

Die Spannung wächst – Inbetriebnahme des ZeKit

Die Inbetriebnahme des fertiggestellten Synthesizers erfolgt am besten über ein Gleichspannungsnetzteil mit 5V bis 9V Versorgungsspannung und einer Stromstärke von 60 bis 500 mA, zum Beispiel 100 mA. Die Steckergröße des Netzadapters beträgt 2,1 mm. Eine Eingangsspannung von mindestens 5V bis maximal 9V wandelt das Board in intern benötigte Spannungen von +3,3V und -2V um. Wer auf Nummer sicher gehen will, nutzt zum ersten Test ein Labornetzgerät, um genaue Versorgungswerte einzustellen. Alternativ wäre eine weitere Option, ein geregeltes Netzteil mit Stromstärken-Limitierung zu nutzen. Ein funktionstüchtiges ZeKit ist daran zu erkennen, dass beim Einschalten die Power-LED leuchtet, die Knöpfe mit roter LED beim Drücken blinken, der Regulatorchip U2 auf der linken oberen Vorderseite des Boards kühl bleibt, sich beim Drücken des Play-Knopfes SW8 dessen Funktion aktiviert, worauf die LED des Schalters SW6 im Gleichtakt blinken sollte. Funktioniert das ZeKit wie vorgesehen, kann der eigentliche musikalische Spaß beginnen.

Nur ein Hindernis steht noch im Weg: Analoge Elektronikkomponenten besitzen Fertigungstoleranzen. So misst beispielsweise ein 10 kOhm Widerstand in der Regel nicht 10 kOhm sondern hat einen um wenige Prozent abweichenden Wert. Das mag für eine einzelne Komponente noch unkritisch erscheinen, kann sich aber bei mehreren Komponenten zu größeren Differenzen aufschaukeln, was sich speziell beim VCF (Voltage-Controlled Filter) auswirkt. Genau dafür gibt es den blauen Trimmer-Poti, der sich über einen passenden Schraubenzieher justieren lässt. Die Details der VCF-Kalibrierung würden diesen Beitrag sprengen. Deshalb sei an dieser Stelle auf die Anleitung hingewiesen.

Die Firmware des ZeKit liegt auf einem Git-Repository [7] als Open Source bereit, lässt sich also nach eigenem Gusto erweitern oder ändern. Weitere Resourcen, Informationen und Sounddemos finden sich auf der ZeKit-Webseite [8].

Signalfluß und Workflow

Musik kreieren auf dem ZeKit können Nutzer zum Beispiel über den Anschluss an eine DAW wie Ableton Live. Zum Experimentieren empfiehlt sich aber auch ein externes Midi-Keyboard (zum Beispiel Arturia KeyStep).

Der Anschluss des Arturia Keystep Midi-Keyboard an den Midi-Eingang des ZeKit ermöglicht ein komfortables Spielen.

Das Sounddesign mit dem ZeKit beginnt mit der Auswahl der gewünschten Wellenformen. Insgesamt stehen je acht monophone und paraphone Wellenformen zur Verfügung.

Dem schließt sich ein analoger Filter an, der die Wahl zwischen einem Lowpass-Filter und einem Bandpass-Filter lässt und eine Flankensteilheit von 12db besitzt. Die Frequenz, ab der ein Abschneiden des Signals erfolgen soll, ist mit dem CUTOFF-Regler einstellbar.

Mittels eines Kippschalters kann der Sounddesigner bezüglich der Resonanz zwischen Chill und Acid wählen. Während Chill eher für sanfte Gemüter gedacht ist, wirkt Acid etwas harscher.

Danach folgt im Signalpfad ein spannungsgesteuerter analoger Verstärker (VCA).

Um den Filter zu modulieren, existiert eine einstellbare Attack-Delay-Hüllkurve. Zur Regelung des Verstärkers dient eine Release-Hüllkurve. Der Hüllkurvengenerator ist loopfähig (siehe Alternativfunktion der REC-Taste), wodurch sich eine weitere niederfrequente Modulationsquelle ergibt, wenn der Musiker ATTACK, RELEASE, ACCENT auf kleine Werte setzt.

Ein spezieller Kippschalter bietet eine Umschaltmöglichkeit zwischen VCF und Mix, dessen Einstellung bestimmt, ob das ZeKit ein extern anliegendes Audiosignal zum Mixer oder zum Filter des ZeKit umleiten soll.

Zum Aufmotzen des Sounds eines ZeKits kann das erzeugte Audiosignal zum Beispiel zu einem Effektmodul geleitet werden, das den Klang um Effekte wie Reverb ergänzt, zumal ZeKit stubenrein ist und keine eigenen Effekte anbietet.

Insofern schreit das ZeKit geradezu danach, eine Liaison mit anderen Geräten einzugehen.

Wer übrigens nach dem Lautstärkeregler sucht: Mittels des LEVEL-Potis ist die Masterlautstärke des ZeKit regulierbar.

Es gibt noch viele weitere wichtige Funktionen. Hier ein Ausschnitt.

  • Mittels WAVE wählen Musiker die gewünschte Wellenform aus.
  • Eigene Motive lassen sich mit RECORD einspielen, im Synthesizer speichern oder mit PLAY wiedergeben. Das Tempo ist über TAP einstellbar. Durch Betätigen der MOTIFS-Taste sind gespeicherte Musiksequenzen wählbar.
  • Zudem haben die Tasten eine weitere alternative Funktion, die sich nach Drücken der Taste OPTIONS einstellt: Bei PLAY/GLIDE feuert der VCF bei jeder Note. Mit REC/LOOP lässt sich der VCF Attack/Release-Hüllengenerator loopen. TAP/TRACK ermöglicht das Key-Tracking der Cutoff-Frequenz. SAVE/RETRIG glättet das Gleiten und die Tonhöhe.
  • Betätigt man WAVE und MOTIFS gleichzeitig, lässt sich für eingehende MIDI-Ereignisse der dafür vorgesehene Kanal einstellen oder das Finetuning des Geräts bestimmen. Im “WAVE+MOTIFS-Modus” synchronisiert sich das ZeKit mit MIDI (PLAY-Taste) oder einem externen Taktgeber (REC). Gleichzeitiger Tastendruck von TAP+SAVE definiert die Zeiteinteilung auf einen Wert von 1-4.
  • Zahlen werden in den entsprechenden Modi immer binär über die Taster 8, 4, 2, 1 eingegeben. Leuchtet die LED eines Tasters, ist an diesem Taster 1 ausgewählt, ansonsten 0. Um 12 zu wählen müssen also die LEDs von Taster 8 und Taster 4 leuchten, die beiden anderen nicht.

(c) Fred’s Lab - Quickstart Guide mit allen Bedienelementen des ZeKit
Fazit

(c) Fred’s Lab, Batterieversorgung als Beispiel für eine eigene Erweiterung

ZeKit ist in gewisser Weise ein Überraschungsei für Maker und Musiker mit Elektronikaffinität. Sowohl der Zusammenbau als auch das Spielen des Synthesizers machen Spaß. Zusätzlich erhalten Maker einen Einblick in die Funktionsweise von Synthesizern. Das gilt umso mehr für diejenigen, die einen genaueren Blick auf Firmware und Hardware wagen. Im Anhang des Montagemanuals hat Fred die genauen Schaltpläne des ZeKit mit Erläuterungen dokumentiert. Ebenso befindet sich dort eine detaillierte Stückliste. Gerade Maker, die schon immer einen Synthesizer kreieren wollten, erhalten beim ZeKit wichtige Anregungen für ihre eigenen Projekte.

Nach dem Zusammenbau kann man das ZeKit so nutzen, wie es ist, oder eigene Mods vornehmen, etwa einen einfacheren Hardware-Mod für zusätzlichen Batteriebetrieb oder einen aufwendigen Hardware+Software-Mod, um ein kleines Display für die Visualisierung hinzuzufügen. Es gibt folglich viele Möglichkeiten, dem ZeKit eine persönliche Note zu verleihen. Der zu anderen Selbstbaukits relativ günstige Preis verursacht kein tiefes Loch im Geldbeutel und offeriert ein exzellentes Preis-Leistungs-Verhältnis.

Vorschau

Noch ist die Miniserie über Selbstbausynthesizer nicht abgeschlossen. In der nächsten Folge soll es um Moog’s jüngsten semimodularen Synthesizer Mavis gehen.


URL dieses Artikels:
https://www.heise.de/-7154810

Links in diesem Artikel:
[1] https://www.heise.de/blog/Frisch-aus-der-Werkstatt-Ein-Selbstbau-Synthesizer-von-Moog-6664968.html
[2] https://www.heise.de/blog/Frisch-aus-der-Werkstatt-Ein-Selbstbau-Synthesizer-von-Moog-6664968.html
[3] https://youtu.be/9wJXOWLeEqM
[4] https://reverb.com/news/the-basics-of-east-coast-and-west-coast-synthesis
[5] https://fredslab.net/en/zekit-module.php
[6] https://www.microchip.com/en-us/tools-resources/develop/mplab-x-ide
[7] https://github.com/Marzac/zekit
[8] https://fredslab.net/en/zekit-module.php
[9] mailto:michael.stal@gmail.com

Copyright © 2022 Heise Medien

Adblock test (Why?)

  • 07. Juli 2022 um 08:04

And now for something completely different – Die Chip-Krise

Von heise online

(Bild: Rowan Morgan/Shutterstock.com)

Eigentlich sollte auf diesem Blog schon längst eine Serie zum Raspberry Pi Zero 2 W beginnen. Doch die Chip-Krise hat dies verhindert.

Eigentlich sollte auf diesem Blog schon längst eine Serie zum Raspberry Pi Zero 2 W beginnen. Doch die Chip-Krise hat dies verhindert, weil sich momentan kein Raspberry-Pi-Board erwerben lässt; zumindest nicht zu vernünftigen Preisen, also für 15 Euro statt für Wucherpreise um die 50 bis 100 Euro. Woran das liegt, möchte der vorliegende Artikel beleuchten.

Am Anfang war Corona

Als wegen des Coronavirus Sars-CoV-2 die jetzige Wirtschaftskrise im Frühjahr 2020 begann, hoffte die Halbleiterindustrie gerade, sich von ihrer eigenen Wirtschaftsflaute zu erholen. Doch das Virus bereitete dieser Hoffnung schon bald ein jähes Ende. Kunden der Chipproduzenten stornierten übereifrig viele Aufträge, etwa die Automobilindustrie. Kurz darauf erholte sich die Nachfrage zwar wieder so stark, dass die Produktionskapazitäten nicht mithalten konnten, aber bis heute leiden viele Branchen und auch die Maker-Szene unter diesem Problem.

Der ein oder andere mag sich noch daran erinnern, dass durch das Corona-indizierte Homeoffice der Bedarf nach Consumer-Electronics (beispielsweise Webcams, Spielekonsolen, Streaming-Hardware) stark anstieg, was das Problem weiter verschärfte.

Von dem Chip-Mangel sind auch zahlreiche Boards aus der Raspberry Pi Familie betroffen
Weitere Ursachen

Es gab allerdings parallel zur Pandemie auch noch andere Ursachen.

Pleiten, Pech und Pannen: Im Winter 2021 fielen wegen eines dramatischen Kälteeinbruchs im texanischen Austin mehrere Fabs aus. Zusätzlich gab es in Japan einen Großbrand in einer für die Automobilindustrie wichtigen Halbleiterfabrik. Das alles in einer Zeit, in der wegen Corona ohnehin weniger Arbeitskräfte verfügbar waren. Zu schlechter-letzt kam Ende des Jahres 2021 wegen Komplett-Lockdowns die Halbleiterproduktion im chinesischen Xian zum Stopp.

Donald Trump: Aufgrund der US-Sanktionen und Handelsbeschränkungen gegenüber China durch Präsident Trump sollten chinesische Elektronikhersteller weniger Halbleiterprodukte aus den USA beziehen können. Das brachte die Firmen dazu, zum einen große Hamsterkäufe benötigter Komponenten zu tätigen und zum anderen, sich stärker auf eigene Füße zu stellen.

Bitcoin & Co: Da wäre auch noch der Run auf Kryptowährungen. Dieser Trend hat zu riesigen Serverfarmen geführt, die mit großem Aufwand Mining betreiben, also das energieintensive Erschaffen neuer Bitcoins. Durch den Anstieg der Energiepreise war das Mining schon bald nicht mehr rentabel, weshalb die professionellen Miner ihre Zelte in China aufschlugen, was der chinesische Staat aber sinnvollerweise schon bald unterbunden hat. Um Mining weiterhin rentabel zu gestalten, bedarf es vieler Rechenressourcen in Gestalt von Hochleistungsgrafikkarten. Das führte schon vor der Pandemie zu Engpässen und letztendlich dazu, dass die Preise für Grafikkarten alle Preisindizes nach oben durchbrachen.

Rohstoffe: Eine wichtige Ingredienz zur Fertigung von Halbleiterprodukten sind die dafür benötigten Ressourcen. Damit ist nicht etwa nur Silizium gemeint, das es sprichwörtlich wie Sand am Meer gibt. Für die Veredelung zu Reinstsilizium sind entsprechende Produktionskapazitäten notwendig, und für Elektronik sind seltene Erden und Metalle unabdingbar. Diese sind aber sehr beschränkt auf unserem Planeten verfügbar. Viele Länder und Firmen konkurrieren um sie. Bis zur Entwicklung geeigneter Ersatzstoffe kann es noch eine Weile dauern.

Quo vadis?

Erst für Ende 2022 haben einige Marktanalysten das Ende dieser Knappheit prognostiziert. Es würden demnach noch einige Monate vergehen, bis sich die Situation wieder einigermaßen beruhigen könnte. Der CEO von Intel, Pat Gelsinger, prophezeit sogar, dass das limitierte Angebot für Chips sich noch bis ins Jahr 2024 erstrecken dürfte. Keine guten Nachrichten also sowohl für die Industrie als auch für Konsumenten.

Was Maker jetzt tun können:

  • Bei Single-Board-Computern wie der Raspberry-Pi-Familie hilft nur, sich bei den bekannten Händlern auf den entsprechenden Online-Seiten anzumelden, um mitzukriegen, dass neue Tranchen zu vernünftigen Preisen wieder verfügbar sind. Erfahrungsgemäß erhalten die größeren Händler immer wieder Lieferungen, die sie aber relativ schnell verkaufen. Allerdings sind Boards wie Raspberry Pi Zero und Zero 2 W jetzt schon über einen längeren Zeitraum nicht mehr in den Lagern der Händler vorzufinden.
  • Im Bereich der Microcontroller-Boards ist die Lage momentan relativ entspannt. Boards wie die der Arduino-Familie, ESP8266- & ESP32-Boards sowie Raspberry Pi Picos sind problemlos verfügbar. Ein Hamstern ist also unnötig. Dennoch empfiehlt es sich, für geplante Projekte die notwendigen Komponenten frühzeitig einzukaufen – sicher ist sicher!
  • Bei den Boards von beispielsweise Microchip oder STM existieren aber durchaus einige Produkte, die voraussichtlich erst 2023 wieder zur Verfügung stehen. Lady Ada von Adafruit gibt dazu einige Hinweise und Informationen in ihrer jungen YouTube-Playlist "Chip Shortage" [1]. Unter dem Titel "The Great Search" hat Adafruit in Zusammenarbeit mit Digi-Key weitere YouTube-Videos bereitgestellt. In diesen Episoden erläutert Lady Ada, wie der Maker für bestimmte Funktionalitäten wie etwa Schaltern herausfinden kann, welche konkreten Produkte es gibt, die alle oder die meisten gewünschten Anforderungen erfüllen. Dadurch lassen sich auch Alternativen zu vergriffenen beziehungsweise nicht verfügbaren Bausteinen finden. Diese YouTube-Videos sind zwar weniger unterhaltend, dafür aber sehr informativ und hilfreich. Wer sich dafür interessiert, sollte auf YouTube nach "The Great Search" und "Adafruit" suchen oder den Adafruit-Blog [2] konsultieren.
Fazit

Die Chip-Krise dürfte uns noch einige Zeit begleiten. Speziell bei der Herstellung leistungsfähigerer und damit komplexerer Chips kommt die momentane Knappheit zum Tragen. Das führt beispielsweise bei Automotive-Anwendungen zu Problemen, aber auch bei Consumer-Produkten.

Zum Glück sind nicht alle Produktkategorien gleichermaßen davon betroffen. Im Microcontroller-Bereich schaut es noch besser aus. Trotzdem erscheint es ratsam, eigene Maker-Projekte bezüglich der Bill of Material rechtzeitig vorab zu planen und die eigene Logistik entsprechend anzupassen. Dieser Blog wird jedenfalls darauf Rücksicht nehmen, zumal es keinen Sinn ergibt, Projekte oder Boards vorzustellen, die der interessierte Maker nicht oder nur zu Wucherpreisen anschaffen kann.


URL dieses Artikels:
https://www.heise.de/-7090001

Links in diesem Artikel:
[1] https://youtube.com/playlist?list=PLjF7R1fz_OOX6EyjN3BYud1VHIqnDyvm_
[2] https://blog.adafruit.com/category/the-great-search/
[3] mailto:michael.stal@gmail.com

Copyright © 2022 Heise Medien

Adblock test (Why?)

  • 13. Mai 2022 um 11:55

Frisch aus der Werkstatt - Ein Selbstbau-Synthesizer von Moog

Von heise online

Frisch aus der Werkstatt - Ein Selbstbau-Synthesizer von Moog

Dr. Michael Stal

(Bild: Moog Music)

In der letzten Episode stand der Korg NTS-1 im Fokus. Das ist aber nicht der einzige verfügbare Synthesizer zum Zusammenbauen.

Vom Urvater aller Synthesizer Robert Moog gibt es einen relativ preisgünstigen Bausatz namens Werkstatt-01. Um diesen "Mini-Moog" soll es im vorliegenden Beitrag gehen.

Werkstatt-01 – des Moogs Kern

Der analoge, einstimmige Moog-Synthesizer Werkstatt-01 kam zum ersten Mal im Jahre 2015 als DiY-Baukasten auf den Markt. Das Produkt umfasst einen kleinen Analogsynthesizer, der Technik von größeren Moog-Synthesizern wie Little Phatty, Sub 37 oder Mini Voyager enthält.

Das Kit ist das Ergebnis des jährlich stattfindenden Moogfests, bei dem Kunden, Künstler und Mitarbeiter die Moog-Produktfamilie zelebrieren. Dazu gehören unter anderem Vorträge und musikalische Sessions. Im Jahr 2014 konnten Interessenten unter Hilfestellung von Moog-Mitarbeitern den kleinen Synthesizer Werkstatt-01 zusammenbauen, sich daran auch nach der Konferenz erfreuen, und außerdem überall und jedermann von diesem Miniatursynthesizer erzählen, was schließlich in der Moog-Community zu einer Euphorie für den Werkstatt-01 führte. Überrascht von dieser positiven Resonanz, beschloss Moog, den DiY-Synthesizer 2015 als Baukasten für alle Interessierten herauszubringen.

Zu Beginn mussten Synthesizer- oder Elektronikfreaks noch über 300 Euro für das Kit hinblättern plus weitere 49 Euro für den optionalen CV-Expander.

2020 hat Moog den Synthesizer neu aufgelegt. Seitdem ist der Bausatz inklusive CV-Expander bereits für rund 215 Euro im Fachhandel erhältlich.

Bauarbeiten

Das Zusammenschrauben beziehungsweise Stecken der Komponenten dauert nicht mehr als zehn Minuten. Alles, was Maker dafür benötigen, ist ein handelsüblicher Philips-Schraubenzieher. Die folgende Bilderstrecke illustriert, welche Schritte dabei nötig sind.

Unboxing: Der Synthesizer kommt gut verpackt an.

Unboxing: Der Synthesizer kommt gut verpackt an.

Sichtung aller gelieferten Teile.

Zunächst montiert der Maker die Gummifüße ans Gehäuse.
Die PCB-Platine kommt per Schrauben aufs Gehäuse

Die PCB-Platine kommt per Schrauben aufs Gehäuse

Ein gutes Zeichen: die rote LED brennt.

Vor dem Aufstecken des Frontpanels sollten angehende Moog-Anwender den Werkstatt-01 über das mitgelieferte Netzteil an den Strom anschließen. Leuchtet die rote LED bei LFO kontinuierlich oder blinkt sie je nach Einstellung des RATE-Drehknopfes, dann funktioniert das Gerät einwandfrei.

Wer auch den CV-Expander am Gerät befestigen möchte, verwendet auf der rechten Gehäuseseite die zwei beigelegten spitzen Schrauben statt der zwei schwarzen Gehäuseschrauben.

Nun wird noch auf der rechten Gehäuseseite der CV-Expander montiert.

Was der Werkstatt-01 unter der Haube bietet

Im letzten Beitrag [1] kamen bereits die grundsätzlichen Elemente eines (analogen) Synthesizers zur Sprache. Trotzdem erfolgt an dieser Stelle nochmals ein Überblick, um auch die Terminologie von Moog kennenzulernen.

Grobarchitektur des Werkstatt-01. Die durchgehenden Pfeile repräsentieren Audiosignale, die gestrichelten Pfeile Kontrollsignale.

Grobarchitektur des Werkstatt-01. Die durchgehenden Pfeile repräsentieren Audiosignale, die gestrichelten Pfeile Kontrollsignale.

(Bild: (c) Moog Music)

Die erste und zentrale Komponente jedes Synthesizers ist ein Oszillator, der Wellen mit bis zu 16 kHz erzeugt. Dieser firmiert unter dem Begriff VCO (Voltage-Controlled Oscillator) und erlaubt beim Werkstatt-01 (Bedienbereich WAVE) entweder Sägezahnwellen (SAW) oder Rechteckswellen (PULSE). Deren Frequenz lässt sich mit dem FREQ-Poti und deren Intensität mit dem PWM-Poti vom Anwender beeinflussen. PWM steht dabei für Pulse-Width-Modulation und bestimmt, wie lange das Signal anliegen (Busy-Phase) und wie lange es nicht anliegen soll (Idle-Phase). Dadurch lässt sich die Intensität des Signals variieren.

Ein Envelope Generator (ENVELOPE beziehungsweise EG) bietet Einstellmöglichkeiten für jeden erzeugten Ton: A = Attack beschreibt die Zeit, bis zu der ein Ton seine maximale Amplitude (Lautstärke) erreicht, S = SUSTAIN regelt die Höhe des Tons (SUSTAIN = ON), und D = DECAY ist dafür verantwortlich, wie lange es am Schluss dauert, bis der Ton wieder die 0 erreicht.

Links unten auf dem Bedienpanel gibt es als weiteren Oszillator den LFO (Low-Frequency Generator), der im Gegensatz zum VCO einen niedrigfrequenten Oszillator darstellt. Als Wellenformen sind Rechteckswellen und Dreieckswellen möglich. Der Schaltpoti RATE stellt die Frequenz des LFO ein. Dessen Wellen sind für das menschliche Ohr nicht hörbar. Aber wozu braucht es dann überhaupt einen LFO?

Oberfächliches Schaltungsdiagramm für den Werkstatt-1

Oberfächliches Schaltungsdiagramm für den Werkstatt-1

Dazu betrachten wir zwischen VCO und LFO den VCO MOD, einen Modulator, der vorgegebene Wellen moduliert. Dessen Quelle (SOURCE) kann dabei entweder der LFO oder der Hüllkurvengenerator (EG) sein. Die Modulation arbeitet dabei als Ziel (DEST) entweder auf der Pulsweitenmodulation (PWM) oder der Frequenz (FREQ) des VCO. Die Intensität beziehungsweise Stärke der Modulation hängt von der Einstellung von AMOUNT ab. Obwohl also die vom LFO erzeugten Wellen für uns nicht hörbar sind, verändern sie angewandt auf den VCO den Sound hörbar. Der LFO spielt also eine wichtige Rolle bei dem Anpassen der Wellenform.

Im Abschnitt rechts neben dem VCO residiert der VCF (Voltage-Controlled Filter), eine Komponente, die aus der im VCO erzeugten Welle Frequenzen herausschneidet oder Resonanz hinzufügt. Mit dem Poti CUTOFF legt der Musiker fest, welche Frequenzen der Synthesizer herausfiltern soll. Damit wird auch der Moog-typische Ladder-Filter mit 24db Flankenanstieg realisiert, der Moog-Synthesizern ihren charakteristischen, "fetten" Ton verschafft. Bei der Resonanz füttert der Synthesizer die Ausgabe des Filters nochmals an den Eingang zurück, was zu einer harmonischen Verstärkung des Tons führt.

Rechts daneben befindet sich der VCA (Voltage-Controlled Amplifier), der entweder auf Basis der Hüllkurve dynamisch arbeitet (EG) oder statisch einen andauernden Ton erzeugt (ON).

Der Modulator namens VCF MOD nutzt als Quelle (SOURCE) entweder den Hüllkurvengenerator (EG) oder den LFO, moduliert dabei mit einer einstellbaren Stärke (AMOUNT) den Filter VCF und kann dabei auch die Polarität umkehren (POLARITY), was erlaubt, die CUTOFF-Frequenz weiter zu senken und damit einen "dunkleren" Sound zu erzeugen. Wenn etwa der VCF MOD den LFO als Quelle nutzt, verschiebt sich dynamisch und regelmäßig die CUTOFF-Frequenz des Filters VCF gemäß dem dazumodulierten LFOs, sodass als Ergebnis ein alarmartiger Klang entsteht.

Der Drehknopf GLIDE dient dazu, den Übergang zwischen zwei aufeinanderfolgenden Tastenanschlägen festzulegen, beantwortet also die Frage, ob sich Töne stakkatoartig, also abrupt abwechseln, oder stattdessen legatoartig sanft ineinander gleiten.

Rechts neben dem GLIDE-Knopf befinden sich übrigens die Tasten, um einzelne Noten einer Oktave zu spielen. Dieser Kompromiss ist der Größe des Synthesizers geschuldet, weil der kleine Synthesizer natürlich keinen Platz für eine echte Klaviatur besitzt. Die unteren acht Eingabeknöpfe entsprechen den weißen Tasten eines Klaviers im Umfang einer Oktave, die fünf oberen Knöpfe den schwarzen Klaviertasten.

In der Spielpraxis empfiehlt sich deshalb eine andere, bequemere Eingabemöglichkeit etwa ein Midi-Keyboard.

Know-How über Synthesizer

Wer sich noch weiter in die Materie Synthesizer einarbeiten möchte, findet grundlegende Infos über Synthesizer auch auf der Webseite von How-Stuff-Works [2].

Wie man mit einem Synthesizer Sounds erstellt, findet sich auf der Webseite bonedo.de [3].

Als Buch empfiehlt sich "Synthesizer. So funktioniert elektronische Klangerzeugung" von Florian Anwander [4].

Modularität durch Patch- und Dupontkabel

Im Großen und Ganzen legt das Gerät also fest, wie seine verschiedenen Sektionen verschaltet sind. Hier ist oft vom Signalpfad die Rede. Durch Wechselschalter lassen sich zumindest alternative Signalpfade definieren, etwa bei der schalterbasierten Wahl zwischen unterschiedlichen Quellen und Zielen beim VCO MOD.

Der am Werkstatt-01 anmontierte CV-Expander – CV steht für Control Voltage – verändert diese Situation, in dem er mittels Patchkabel erlaubt, eigene Signalpfade zu definieren. Dadurch lässt sich der Werkstatt-01 vereinfacht als semimodularer Synthesizer betrachten. Nebenbei bemerkt: Ohne Integration des CV-Expanders lassen sich diese Verbindungen mittels eingesteckter Dupontkabel vorgeben.

Am CV-Expander lassen sich neue Signalpfade per Patch-Kabel schalten, die zu interessanten Sounds führen.

Grundsätzlich gibt es folgende Ausgänge: VCO OUT, VCF OUT, LFO OUT, EG OUT, TRIG OUT, GATE OUT, KB CV OUT, CV OUT.

Und als Eingänge: VCF OUT IN, GATE IN, LFO IN, VCO EXP IN, VCO LIN IN, VCA IN, CV IN.

Wer also einen Eingang mit einem Ausgang verbindet, kann völlig neue Konfigurationen definieren. Der Synthesizer bietet für jeden Ausgang zwei Ports, für jeden Eingang einen Port. Damit lassen sich von jedem Ausgang per Kabel bis zu zwei Eingänge ansteuern.

Mögliche Beispielskonfiguration: Musiker verbinden per Dupontkabel oder Patchkabel den Ausgang des Envelope Generators mit dem Eingang des LFO. Dadurch beeinflusst das vom Envelope Generator ausgehende Spannungssignal die Frequenz des LFOs, was zu einem speziellen oszillierenden Ton mit sich vergrößernden Dämpfung führt.

Benutzung und Kalibrierung des Synthesizers

Zunächst lohnt es sich, mit dem Synthesizer zu experimentieren. Einfach einen Kopfhörer in die 6,3 mm-Buchse anschließen und schon kann es losgehen.

Das Werkstatt-01 Exploration Patchbook [5] ist ein guter Ausgangspunkt, um zu lernen, wie sich verschiedene Soundeffekte mittels Patchkabel am CV-Expander erzielen lassen.

Einbringen von Verzerrung mittels zweier Patchkabel.

“Pick up the Phone” ist ein weiterer Patch-Vorschlag.

Auf der SoundCloud [6] finden sich unter der Suchzeichenkette “moog werkstatt” allerlei Beispiele für im Werkstatt-01 produzierte Sounds.

Den Anschluss externer Hardware, zum Beispiel des Midi-Keyboards Arturia KeyStep Pro an den Werkstatt-01 über den CV-Expander, zeigt exemplarisch ein Video des amerikanischen Händlers Sweetwater [7] ().

Beim Anschließen externer Hardware kann es freilich passieren, dass die Oktave auf dem Moog nicht mehr richtig kalibriert ist, was zum Beispiel zu einer Abweichung von einem Halbton führen kann, weil etwa aus dem oberen C ein C# wird. In diesem Fall muss der Anwender den Synthesizer kalibrieren. Dazu gibt es sowohl Anleitungen auf YouTube [8] als auch ein Manual [9]. Normalerweise deckt 1 V auf dem Synthesizer eine Oktave ab, aber durch Anschluss eines externen Geräts ist es möglich, dass sich hier etwas verschiebt, was sich durch den Trimpoti VCO EXP TRIM kalibrieren lässt. Der sitzt direkt auf dem eingebauten PCB-Board. Zum Kalbrieren reicht also das VCO-EXP-TRIM-Poti plus ein Instrumententuner, den es als Hardware oder als Smartphone-App gibt.

Mods

Den Synthesizer von Moog betrachtet der Artikel vor allem wegen seiner Ausbaufähigkeiten. So können Anwender unter anderem den LFO zu einem zweiten VCO umbauen, per Arduino oder einem anderen Microcontroller einen Arpeggiator konstruieren oder einen wabbelnden Klang erzeugen, eine Pitchbend-Möglichkeit oder einen Noise-Generator hinzufügen, und vieles mehr.

Dazu gibt es von Moog und anderen wertvolle Anregungen [10]. Ein ganzes Tutorial für Synthesizer Mods [11] findet sich zum Beispiel hier.

Für die Mods sind im wesentlichen einfache Bausteine wie Breadboards, Dupontkabel, Widerstände, Potis und Kondensatoren notwendig. Bei ausgefeilteren Mods kommen auch schon einmal Arduino Boards oder 555-ICs zum Einsatz. Jeder Mod benötigt den GND des Werkstatt-01. Dazu öffnet der Maker das Gehäuse, und verbindet das abisolierte Ende eines schwarzen Dupontkabels mit einer der inneren Schrauben, die das Synthesizerboard am metallenen Gehäuserahmen befestigen. Führt man das andere Ende dieses Kabels nach außen, lässt es sich mit der Schaltung des Mods als Common Ground verbinden.

Auf Sparkfun gibt es weitere Anregungen [12].

Die Schaltpläne des Werkstatt-01 hat Moog ebenfalls bereitgestellt -> Schematics [13].

Eine etwas komplexere Modifikation betrifft die Nutzung des VCO-Signals als Oszillator eines weiteren Synthesizers [14].

Der Besitzer des Werkstatt-01 offeriert also eine ganze Palette an Möglichkeiten zum Erweitern.

Auch andere Mütter haben schöne Töchter

Sowohl der Moog Werkstatt-01 als auch der Korg NTS-1 kamen in diesem Blog zur Sprache, weil sie ermöglichen, Themen wie Elektronik und Musik, Mikrocontroller, Embedded Software zu adressieren. Die beiden vorgestellten Kits sind nicht mehr die jüngsten, stammen dafür von bekannten, innovativen Unternehmen, haben eine große Community, und lassen sich modifizieren beziehungsweise erweitern.

Wer einen ausgefeilten DiY-Synthesizer zu einem günstigen Preis sucht, sollte die Webseite von Zynthian besuchen. Bei Zynthian handelt es sich um eine Open Synth Software und gleichzeitig um eine Linux-Distribution für den Raspberry Pi (3 oder 4). Wer die Community unterstützen möchte, ordert das zugehörige Kit (aktuelle Version [15]). Ein Zynthian-Gerät lässt sich aber auch mit einfachen Mitteln selbst entwerfen und zusammenbauen. Von Floyd Steinberg gibt es dazu ein passendes YouTube-Video [16], in dem aus einem Raspberry Pi Board, einem kleinen Touch-Display und einem Midi-USB-Kabel ein Zynthian-Synthesizer entsteht.

Die Axoloi Community [17] hat ein Board erstellt (Axoloti Core), mit dem sich unter Zuhilfenahme einer außergewöhnlichen Software, dem Axoloti Patcher, coole Sachen machen lassen. Es könnte aber unter Umständen schwierig sein, ein solches Board zu erwerben. Zumindest hatte der Autor damit Probleme.

Weitere Kits stellt die britische Webseite TheVinylFactory [18] in einem Artikel vor.

Für Synthesizer-Interessierte mit mehr Bezug zum Musikmachen als zu Elektronik und Embedded Systemen, gibt es schon für wenige Hundert Euro sehr leistungsfähige Geräte. So eignen sich für den Einstieg zum Beispiel der Korg Minilogue XD oder der Wave-basierte ASM HydraSynth-Explorer, der Roland JD-Xi, der Arturia MicroFreak, der Behringer DeepMind 6, oder der Yamaha MX49 V2.

Fazit

In dieser und der vorherigen Folge kamen die Synthesizer Korg NTS-1 und Moog Werkstatt-01 zur Sprache. Beide Kits stammen von renommierten Unternehmen, verfügen wegen ihres Alters über große Communitys, und erweisen sich als gut erweiterbar mittels eigener Software und Elektronik. Sie vermitteln Grundkenntnisse in puncto Synthesizer, und lassen sich durch die große Zahl von Informationsquellen leicht durchdringen. Während der Werkstatt-01 das Patchen über Kabel erlaubt, trumpft der NTS-1 mit mehr Schnittstellen auf. Das Experimentieren mit ihnen macht Spaß, weil man sie gut in die eigene Sound-Konfiguration integrieren kann. Beim ein oder anderen wird dadurch vielleicht der Funken entzündet, es auch mal mit ausgewachsenen Geräten zu versuchen.


URL dieses Artikels:
https://www.heise.de/-6664968

Links in diesem Artikel:
[1] https://www.heise.de/blog/Korg-NTS-1-Elektronik-trifft-auf-Musik-6658911.html
[2] https://electronics.howstuffworks.com/gadgets/audio-music/synthesizer.htm
[3] https://www.bonedo.de/artikel/crashkurs-synthesizer-und-sounddesign/
[4] https://www.amazon.de/Synthesizer-So-funktioniert-elektronische-Klangerzeugung/dp/3941531700/ref=sr_1_1?__mk_de_DE=%C3%85M%C3%85%C5%BD%C3%95%C3%91&crid=MZ22TAN7M8MP&keywords=synthesizer&qid=1648769229&rnid=1703609031&s=books&sprefix=synthesizer%2Caps%2C98&sr=1-1
[5] https://api.moogmusic.com/sites/default/files/2020-10/Werkstatt-01_Patchbook_2020.pdf
[6] https://soundcloud.com
[7] https://m.youtube.com/watch?v=xfWauY8H8J0
[8] https://m.youtube.com/watch?v=vVNI3jibZ4U
[9] https://api.moogmusic.com/sites/default/files/2018-04/Werkstatt_Expansion_Board_Final.pdf
[10] https://www.moogmusic.com/media/werkstatt-01-projects-mods
[11] https://back.moogmusic.com/sites/default/files/2020-10/Werkstatt_Modification_Handbook.pdf
[12] https://www.sparkfun.com/news/1617
[13] https://api.moogmusic.com/sites/default/files/2018-04/Werkstatt_01_Schematics.pdf
[14] https://synthnerd.wordpress.com/category/moog-werkstatt/
[15] https://shop.zynthian.org/shop/product/zynthian-kit-v4-6-448?category=13
[16] https://youtu.be/Aq9Bavd7OqY
[17] http://www.axoloti.com/
[18] https://thevinylfactory.com/features/8-diy-analogue-synthesizers-you-can-build-at-home/
[19] mailto:rme@ix.de

Copyright © 2022 Heise Medien

Adblock test (Why?)

  • 07. April 2022 um 06:58

Korg NTS-1 – Elektronik trifft auf Musik

Von heise online

Korg NTS-1 – Elektronik trifft auf Musik

Dr. Michael Stal

Der Synthesizer ist ein Paradebeispiel für die Symbiose aus Musikinstrumentenbau und Elektronik. Ein kleiner Bausatz macht Appetit darauf.

Egal ob Tonabnehmer, Instrumententuner oder Effektgeräte für Gitarristen - schon vor langer Zeit sind Musikinstrumentenbau und Elektronik eine erfolgreiche Symbiose eingegangen, anfangs bei Gitarren und Keyboards. Als Paradebeispiel für die vollständige Verschmelzung beider Disziplinen fungieren Synthesizer, weshalb in diesem Beitrag ein kleiner Bausatz im Vordergrund stehen soll.

Es fängt nicht immer klein an

1964 erschuf der legendäre Robert Moog den weltweit ersten analogen Synthesizer. Er hat anfangs die Geräte dieser Gattung als raumfüllende Spezialanfertigungen für Musikstudios konzipiert. 

Erst ab 1970 wurden Synthesizer wie der kompakte Minimoog einem breiteren Publikum zugänglich und inspirierten andere Unternehmen dazu, auf Moogs Spuren zu wandeln. Firmennamen wie Korg, Roland, Akai oder Oberheim dürften für die meisten Musikgenießer bekannt klingen.

Heutzutage existieren Synthesizer in allen Leistungs- und Preisklassen. Korg, AKAI, Roland und selbst Moog bieten entsprechende Produkte für wenig Geld an. 

Für noch weniger Geld lassen sich freilich im Apple App Store oder Google Play Store Apps erwerben, die ganze Synthesizer simulieren, darunter auch legendäre Geräte wie den Minimoog. Aber seien wir ehrlich: An die akkustischen und haptischen Momente mit echter Hardware kommen virtuelle Synthesizer nicht ran.

Wer aus Elektroniksicht tiefer in die Materie eintauchen und die innere Arbeitsweise von Synthesizern kennenlernen möchte, geht ins Museum oder legt selbst Hand an. Und dafür eignet sich insbesondere der Korg NTS-1, ein als Baukasten ausgelieferter minimalistischer Synthesizer. Es ist beileibe nicht der einzige Synthesizer-Bausatz, aber eindeutig einer der interessantesten. 

Der Mini-Synthesizer NTS-1 von Korg ist als Bausatz konzipiert.

Übrigens werde ich in einem Folgeartikel auch noch auf den Moog Werkstatt-01 eingehen, den Interessierte ebenfalls als Bausatz erwerben können, um sich als Besitzer eines Moog betrachten zu können.

Was ist ein Synthesizer?

Ein Synthesizer setzt per Klangsynthese in Echtzeit auf elektronischem Weg Klänge zusammen. Die Ansteuerung der synthetisierten Klänge kann durch einen Sequenzer (spielt gespeicherte Klangfolgen), einen Arpeggiator (spielt Akkorde) oder durch eine Klaviatur (spielt alle gedrückten Tasten) erfolgen. 

Dabei synthetisiert ein monophoner Synthesizer nur einen Ton gleichzeitig, ein polyphoner Synthesizer hingegen mehrere. Die Elektronik eines Synthesizers, egal ob mono- oder polyphon, kann dabei  analog, digital oder hybrid arbeiten.

Der erste Baustein, den Musiker auf einem Synthesizer vorfinden, ist ein sogenannter VCO (Voltage-Control-Oscillator), der eine Welle als Fundament erzeugt. Ein VCO erlaubt das Generieren von Wellen in verschiedenen Formen, Frequenzen und  Amplituden. Als Wellenform treten häufig Sinuskurven, Sägezahn-, Dreieck- und Rechteckformen (Pulse) auf. Synthesizer wie der Korg-NTS1 erlauben zusätzlich benutzerdefinierte Wellenformen. Während eine Sinuswelle einen  “sauberen” Ton erzeugt, weisen andere Wellenformen unterschiedliche charakteristische Obertöne (sogenannte Harmonics) auf. Das gilt auch für Musikinstrumente, weshalb mancher Synthesizer bei Wahl der richtigen Modellierungsparameter „echte“ Musikinstrumente sehr realitätsnah nachahmen kann.

Im Bereich Filter legen Anwender – nomen est omen – diverse Filter für den erzeugten Ton fest, zum Beispiel Low-Pass-, High-Pass- und Band-Pass-Filter. Das geschieht mittels einer Cut-Off-Frequenz, die die Grenze für das Abschneiden der Frequenz festlegt. Ein Low-Pass-Filter definiert beispielsweise eine Cut-Off-Frequenz, ab der ein Synthesizer die höherfrequenten Klanganteile herausfiltert, sodass nur noch die niedrigeren Frequenzen den Filter passieren können. 

Synthesizer stellen in der Regel einen LFO (Low Frequence Oscillator) zur Verfügung, mit dessen Hilfe sich die  erzeugte Wellenfunktion modulieren lässt. Normalerweise sind niederfrequente Wellen für den Menschen nicht wahrnehmbar. Sobald Nutzer den LFO allerdings dafür einsetzen, um eine andere (hörbare) Welle zu modulieren, verleiht er dem erzeugten Ton eine auch im menschlichen Ohr wahrnehmbare, spezielle Charakteristik. Mittels der Frequenz des LFO lässt sich so die Intensität der modulierten Welle festlegen, mit dessen Amplitude die Stärke des wahrnehmbaren Modulationseffekts. Mit einem LFO ist es beispielsweise möglich, Tremoloeffekte zu erzeugen.

Danach kommt der EG (Envelope Generator) zum Einsatz, der eine ADSR-Amplitudenhüllkurve definiert. Die einzelnen Buchstaben stehen für die Parameter Attack (Zeit bis der Ton sein Maximum erreicht), Decay (Zeit bis der Ton auf ein geringeres Plateau fällt), Sustain (Tonhöhe nach dem Decay) und Release (Zeit bis der Ton zu guter letzt wieder auf die Amplitude 0 fällt).

Zusätzlich ermöglichen Synthesizer das Anwenden diverser Effekte auf den Klang, etwa Reverb und Delay. 

Ein Arpeggiator sorgt bei einem anhaltenden Tastendruck dafür, dass nicht nur ein einziger Ton sondern sequenziell die Töne eines Akkords abgespielt werden. Dabei lässt sich zum Beispiel  festlegen, welche Oktave der Synthesizer abspielt, welchen Akkordtyp er dafür nutzt, wie lange jeder Ton anhält, wie lange die Pause zwischen Tönen dauern soll, und vieles mehr.

Wer glaubt, ein monophoner Synthesizer könne automatisch nur einen VCO besitzen, der liegt falsch. In einem monophonen Synthesizer können mehrere VCOs für schwebende Klänge sorgen. Polyphone Synthesizer besitzen hingegen immer mehrere VCOs, mit denen sich verschiedene Tonhöhen und deshalb auch Akkorde spielen lassen. Sie integrieren einen Mixer, mit dessen Hilfe der Musiker bestimmt, aus welchen Anteilen der diversen VCOs der resultierende Klang sich zusammensetzt. Das ist notwendig, weil etwa eine Sägezahnwelle durchsetzungsfähiger ist als eine Sinuswelle. In diesem Fall reicht von ersterem Signal oft ein kleinerer Anteil als vom zweiten Signal.

Das Schaltbild des weiter unten besprochenen monophonen Korg NTS-1 enthält alle genannten Komponenten: Oscillator (VCO), Filter, Envelope Generator, Modulator (LFO) sowie die Effekte Delay und Reverb. Durch Schalter (->Route) lassen sich auf Wunsch ein, zwei oder drei der letztgenannten Bausteine umgehen. Zusätzlich gibt es einen Eingang, um den Synthesizer von außen anzusteuern (etwa über ein Midi-Keyboard, Effektgeräte, oder andere Synthesizer) sowie Ausgänge für Kopfhörer beziehungsweise Lautsprecher oder andere nachgeschaltete Geräte (zum Beispiel Recorder, Sampler, Mixer). Mittels eines Arpeggiators lassen sich gemäß eingestellten Akkorden Sequenzen von so erzeugten Klängen abspielen. 

Die Schaltung des NTS-1 zeigt die vorgebenene Reinhenfolge seiner Klangkomponenten.

In den meisten Synthesizern ist die dargestellte Signalkette mehr oder weniger fest integriert. Speziell modulare Synthesizer bieten dagegen die Möglichkeit, einzelne Komponenten beispielsweise über Patchkabel miteinander zu verbinden, um auf diese Weise beliebige Signalketten zu konfigurieren. Besonders die früheren Synthesizer waren an der verwirrenden Vielzahl ihrer Patchkabel zu erkennen. In einem YouTube Video [1] aus dem Jahr 1970 demonstriert Wendy Carlos dieses Vorgehen. Sie war Mitarbeiterin des Synthesizer-Pioniers Robert Moog und erlangte 1968 als Künstlerin mit dem Album “Switched-on Bach” Berühmtheit, auf dem – wie sollte es anders sein – ein Moog-Synthesizer zum Einsatz kam.

Insgesamt stellt ein Synthesizer also sehr viele Stellschrauben zur Verfügung, mit denen sich gefühlt unendlich viele Sound-Landschaften gestalten lassen. Jeder Synthesizer verfügt über spezielle Hardwareeigenschaften, die das Klangbild mitbestimmen. So besitzen Synthesizer von Moog einen sehr charakteristischen “fetten” Klang.

Es gibt auch Synthesizer, die andere Verfahren nutzen, etwas Wavelists und Waveforms wie der ASM HydraSynth. Deren Potenzial ist wesentlich größer, dafür die Umsetzung von Klangideen meistens aufwendiger. Auf diese alternativen Konzepte geht der vorliegende Artikel aus Platzgründen nicht ein.

Do it yourself

Für den Preis und die Mächtigkeit eines Synthesizers gibt es scheinbar keine Grenze nach oben. Das  gilt aber nicht für den Geldbeutel und die Wünsche von uns Normalsterblichen. Zum Glück geht es auch sehr günstig und minimalistisch.  Der hybride monophone Korg NTS-1 richtet sich zum einen an diejenigen, die Erfahrung mit einem Synthesizer erwerben wollen, und zum anderen an erfahrene Zeitgenossen, die das Gerät als zusätzliche Möglichkeit betrachten, eigene Soundquellen aufzupeppen. Für einen Straßenpreis von 99 Euro können Interessenten den Bausatz erwerben, der neben dem Kurzmanual auch einen QR Code  enthält. Letzterer verweist auf eine Korg-Webseite mit der visuellen Bauanleitung für den NTS-1 [2], wobei der Begriff “Bausatz” auf einige abschreckend wirken könnte. Genau genommen, besteht das Zusammenbauen in diesem Fall nicht aus Löten, sondern im wesentlichen aus dem Zusammenstecken zweier Platinen und dem Zusammenschrauben des Gehäuses. 

Zu Beginn verschafft sich der angehende Synthesizer-Besitzer einen Überblick über die Einzelteile.

Das “Zerbrechen” der großen Platte in ihre Einzelteile (Platinen) anhand der perforierten Schnittstellen, ist dabei noch das kritischste Manöver.  Genau genommen, ist das Zusammenbauen selbst für Zeitgenossen mit zwei linken Händen keine echte Herausforderung. Die ganze Montage ist deshalb in gut einer halben Stunde erledigt.

Sobald der NTS-1 über ein Micro-USB-Kabel zum ersten Mal Strom erhält, fährt das Gerät hoch, und gibt durch das Aufflackern diverser LEDs und Texten in der Anzeige ein erstes Lebenszeichen von sich. Wer über die 3,5mm-Klinkenbuchse an der Gehäusefront einen Kopfhörer anschließt, kann sofort mit dem Experimentieren anfangen. Das Gerät integriert aber auch einen eingebauten Lautsprecher mit geringer Leistung als Nice-to-have-Feature. Die aufgeklebte Miniklaviatur dient der Bedienung. Das ist zwar pragmatisch, aber nicht besonders bequem. Besitzer eines Midi-Keyboards können dieses per Midi-Kabel mit dem Midi-in-Eingang des NTS-1 verbinden (Typ: TRS-A 3,5mm-Klinkenbuchse), was die Bedienung spürbar erleichtert. Über den Audio-in-Eingang lassen sich eigene Tonquellen anschließen.  Zwei weitere Buchsen  Sync-In/-Out  helfen bei der Synchronisation mit und über andere Geräte.

Nach einer halben Stunde Zusammenbauen ist der Synthesizer einsatzbereit.

Ein paar Proben gefällig? Als Appetithäppchen hat Korg ein paar Soundbeispiele auf der Soundcloud [3] veröffentlicht (Suchstring: “Korg NTS-1”). Dort lässt sich ein erster Eindruck von den vielfältigen musikalischen Möglichkeiten des Miniatur-Synthesizers gewinnen.

Dass der Synthesizer nicht als Spielzeug konzipiert ist, liegt auf der Hand, zumal er dieselben Komponenten verwendet, die auch bei seinen “ausgewachsenen” Brüdern Korg Minilogue XD und Korg Prologue zum Einsatz kommen. Der Autor als Besitzer eines Korg Minilogue und eines Minilogue XD kann das aus eigener Erfahrung bestätigen.

Programmierschnittstelle

Der NTS-1 ist deshalb auch kompatibel mit dem logue-SDK der Synthesizerproduktfamilie bestehend aus Korg  Minilogue, Korg Monologue und eben auch Korg NTS-1. Die zugehörigen Dateien befinden sich auf einem Github-Repository [4]. Als Programmiersprache liegt C++ zugrunde. Diverse Hobbyisten und Profis haben damit bereits zum Teil sehr ausgefeilte eigene Effekte und Oszillatoren entwickelt. Eine Sammlung von freien Oszillatoren ist beispielsweise über die Webseite [5] verfügbar. Bei einer Websuche finden sich aber noch wesentlich mehr Effekte und Oszillatoren sowie YouTube-Videos zu dem Thema.

Wer keine Lust hat, das SDK programmatisch zu nutzen, kann stattdessen auf Windows oder macOS die Software NTS-1 digital Librarian [6]installieren, die das bequeme Laden und Verwalten von vorgefertigten  Oszillatoren und Effekten über eine grafische Oberfläche unterstützt ). Damit lassen sich allerlei mächtige Funktionalitäten auf das Gerät laden. 

Wer noch mehr Futter für den NTS-1 braucht, findet bei Hammond Eggs Music [7] passende logue-Plug-ins für alle Korg-Produkte aus der logue-Familie (NTS-1, Prologue und Minilogue XD).

Die spartanische GUI des NTS-1 digital Librarian.

Übrigens: Momo Müller bietet für 6,90€ einen interaktiven Editor [8] für den NTS-1 sowohl als Standalone-Programm als auch als VST-Plug-in an. Damit lässt sich der Synthesizer problemlos in eine DAW (Digital Audio Workstation) der Wahl integrieren.

Korg NTS-1 Editor und Soundbank von Momo Müller.

Der spanischen Entwickler Oscar RC stellt einen kostenlosen Webeditor für den NTS-1 zur Verfügung, der als PWA (Progressive Web Application) sogar offline funktioniert. Die Quellen dazu gibt es auf GitHub [9]

Der kostenlose Webeditor des spanischen Entwicklers Oscar RC.

Hardwareanbauten

Sogar das Erstellen einer eigenen Frontplatte für den NTS-1 ist denkbar. So findet sich auf der Webseite [10] eine alternative Frontplatte für den NTS-1, die sich über Arduino-Shields erweitern lässt. Auf der genannten Webseite gibt es noch weitere Custom Front Panels und den Verweis auf einen ausführlichen Arduino-Sketch mit einem Sequencer-Template. Ein zusätzliches YouTube-Video [11] erläutert den Austausch der normalen Frontplatte mit der gerade beschriebenen alternativen Frontplatte. 

Fazit

Synthesizer sind heute nicht mehr von professionellen Musikproduktionen wegzudenken. Das Arbeiten mit ihnen macht nicht nur Musikenthusiasten sehr viel Spaß. Wer wissen möchte, wie ein Synthesizer intern funktioniert, erlebt mit Bausätzen wie dem Korg NTS-1 zwar keine Erleuchtung, aber zumindest interessante Einblicke, gerade weil sie minimalistisch gehalten sind. Zur Hilfestellung gibt es auf YouTube zahlreiche informative Videos nicht nur allgemein über Synthesizer, sondern auch speziell über den NTS-1.

Apropos YouTube. Wer noch mehr über den NTS-1 erfahren will. Unter dem Link [12] finden sich Dutzende Videos zu diesem Thema.

Ohnehin ist es spannend, dass es um den NTS-1 inzwischen eine große Community gibt.  Nicht schlecht für einen preisgünstigen DiY-Synth. Natürlich lässt der Name des Geräts vermuten, dass es irgendwann auch einen NTS-2 geben könnte. Einige NTS-1-Liebhaber scharren deshalb schon mit ihren Hufen.

Wer den Bausatz erwerben möchte, besucht am besten die Webseiten großer Fachgeschäfte. Für den vorliegenden Artikel hat der Autor sein Exemplar bei Thomann [13] erworben.


URL dieses Artikels:
https://www.heise.de/-6658911

Links in diesem Artikel:
[1] https://www.youtube.com/watch?v=4SBDH5uhs4Q
[2] https://m.youtube.com/watch?v=g_310MHzd0o&feature=emb_logo
[3] https://soundcloud.com
[4] https://github.com/korginc/logue-sdk
[5] https://korginc.github.io/logue-sdk/unit-index/
[6] https://www.korg.com/de/products/dj/nts_1/librarian_contents.php
[7] https://hammondeggsmusic.ca/logueplugins.html
[8] https://korg-nts-1-editor-soundbank.jimdofree.com/#link1
[9] https://github.com/oscarrc/nts-web
[10] https://korginc.github.io/nts-1-customizations/
[11] https://m.youtube.com/watch?v=dL5zSNJrvd8&feature=emb_imp_woyt
[12] https://m.youtube.com/results?sp=mAEA&search_query=nts-1
[13] https://www.thomann.de/de/korg_nts_1.htm
[14] mailto:rme@ix.de

Copyright © 2022 Heise Medien

Adblock test (Why?)

  • 31. März 2022 um 16:10
❌