In der Welt der Arduino Programmierung bietet das Schlüsselwort „struct“ eine kraftvolle Möglichkeit zur effizienten Datenverwaltung. Anders als Arrays erlaubt ein struct die Gruppierung verschiedener Datentypen unter einem Dach – und das mit variablen, aussagekräftigen Namen. Bevor wir jedoch tiefer in die Vorteile von struct eintauchen, werfen wir einen Blick auf das Problem, dem viele Entwickler gegenüberstehen: Arrays. Diese, obwohl leistungsstark, sind auf einen Datentyp beschränkt und verlangen eine festgelegte Größe. Das Finden spezifischer Daten wird so zu einer Herausforderung.
Verkürzt kann man quasi sagen: Ein struct
(Abkürzung für „structure“) ist in der Welt der Arduino Programmierung, die auf C++ basiert, eine Datenstruktur, die es ermöglicht, verschiedene Datentypen unter einem gemeinsamen Namen zu organisieren und zu gruppieren.
Inhaltsverzeichnis
- Wie ist ein struct aufgebaut?
- Wie wird ein struct erzeugt?
- Ein Beispiel für den Einsatz eines struct am Arduino
- Erkannte Vorteile eines struct
- Nachteile eines struct durch die öffentliche, einfache Struktur
Wie ist ein struct aufgebaut?
Ein struct
ist eine Datenstruktur, die es erlaubt, verschiedene Datentypen unter einem gemeinsamen Namen zu gruppieren. Technisch gesehen wird ein struct
als benutzerdefiniertes Datentyp betrachtet, der aus einer Sammlung von Datenmitgliedern besteht. Im Gegensatz zu Klassen, haben structs
standardmäßig öffentlichen Zugriff auf ihre Datenmitglieder, während Klassen standardmäßig private Zugriffsbereiche haben.
struct Sensordaten{ // Datentyp1 variablenname1; // Datentyp2 variablenname2; // ... };
Wir können also für einen Sensor folgendes struct erzeugen.
struct Sensordaten{ String typ; float value; };
Wie wird ein struct erzeugt?
Das struct wird behandelt wie eine Variable, d.h. zunächst nennen wir den Datentypen, was in unserem Fall der Name des struct ist und danach einen Namen.
Du kannst dann entweder gleich Werte zuweisen oder dieses später in einer Funktion erledigen.
Sensordaten temperatur = { "Temperatur", 12.64 };
Wenn du die Initialisierung der Daten des struct später erledigst, dann solltest du sicherstellen, dass dieses vor dem Lesen / verwenden der Daten erfolgt. Es würde dir kein Fehler geworfen werden, sondern du erhältst einfach irgendwelche Daten aus dem Speicher.
Sensordaten temperatur; void setup(){ temperatur.type = "Temperatur"; temperatur.value = 12.56; }
Ein Beispiel für den Einsatz eines struct am Arduino
Steigen wir nun mit einem Beispiel ein, ich möchte gerne die Sensordaten eines DHT11 Sensors verwalten. Dieser Sensor liefert die Temperatur, sowie die relative Luftfeuchtigkeit.
Diese Daten wollen wir jetzt in einem struct speichern. Dazu legen wir uns zunächst erstmal die Struktur an.
struct Sensordaten { String type; //der Typ (Temperatur, rel. Luftfeuchtigkeit, Luftdruck etc.) String symbol; //das Zeichen/Symbol für die Maßeinheit (°C, %, hPa) float value; //der aktuelle Wert float max; //der maximal gemessene Wert float min; //der minimal gemessene Wert };
Hier der komplette Code zum Auslesen der Temperatur und rel. Luftfeuchtigkeit eines DHT11 Sensors am Arduino UNO R3.
//Bibliothek zum kommunizieren mit dem DHT Sensor #include <dhtnew.h> //der Sensor ist am digitalen Pin D5 angeschlossen DHTNEW dht11Sensor(5); //struct für die Verwaltung der Sensordaten struct Sensordaten { String type; String symbol; float value; float max; float min; }; //erzeugen von Feldern für die Sensordaten //des DHT11 Sensors Sensordaten temperatur; Sensordaten luftfeuchte; void setup() { //begin der kommunikation mit 9600 Baud //auf der seriellen Schnittstelle Serial.begin(9600); //definieren der Daten für den Temperaturwert temperatur.type = "Temperatur"; temperatur.symbol = "°C"; temperatur.value = 0; //maximale und minimale Grenze setzen temperatur.max = -999; temperatur.min = 999; //definieren der Daten für //die relative Luftfeuchtigkeit luftfeuchte.type = "rel. Luftfeuchtigkeit"; luftfeuchte.symbol = "%"; luftfeuchte.value = 0; luftfeuchte.max = -999; luftfeuchte.min = 999; } //Funktion zum ausgeben von Sensordaten //auf der seriellen Schnittstelle //Als Parameter wird das struct übergeben. void printValues(Sensordaten data) { Serial.println(data.type); Serial.print("\taktueller Wert: "); Serial.print(data.value); Serial.print(data.symbol); Serial.print("\t"); Serial.print("(max.: "); Serial.print(data.max); Serial.print(data.symbol); Serial.print(", min.: "); Serial.print(data.min); Serial.print(data.symbol); Serial.print(")"); Serial.println(); } void loop() { //anfordern der Sensordaten dht11Sensor.read(); //behandeln der Werte für die rel. Luftfeuchtigkeit float luftfeuchteValue = dht11Sensor.getHumidity(); luftfeuchte.value = luftfeuchteValue; luftfeuchte.max = max(luftfeuchteValue, luftfeuchte.max); luftfeuchte.min = min(luftfeuchteValue, luftfeuchte.min); //behandeln der Werte für die Temperatur float temperatureValue = dht11Sensor.getTemperature(); temperatur.value = temperatureValue; temperatur.max = max(temperatureValue, temperatur.max); temperatur.min = min(temperatureValue, temperatur.min); //ausgeben der Daten auf der seriellen Schnittstelle printValues(luftfeuchte); printValues(temperatur); //eine kleine Pause von 1,5 Sekunden delay(1500); }
Der Code erzeugt eine Ausgabe auf der seriellen Schnittstelle aus welcher wir die aktuellen sowie der maximale und minimale Wert ablesen können.
Erkannte Vorteile eines struct
Wenn wir nun auf den Code blicken, erkennen wir zunächst vier eindeutige Vorteile eines struct.
Datenorganisation: structs
ermöglichen die Gruppierung verschiedener Datentypen unter einem gemeinsamen Namen. Dies fördert die organisierte Strukturierung von Daten, was besonders nützlich ist, wenn verschiedene Informationen zu einem einzigen Konzept gehören.
Verbesserte Lesbarkeit: Durch die Verwendung von structs
können Daten mit aussagekräftigen Namen versehen werden. Dies verbessert die Lesbarkeit des Codes, da Entwickler auf einen Blick erkennen können, welche Daten ein bestimmtes struct
repräsentiert.
Einfacher Zugriff: Der Zugriff auf die Mitglieder eines structs
erfolgt über die Punkt-Notation, was den Code einfacher und intuitiver macht. Dies erleichtert das Lesen, Schreiben und Verstehen von Daten, insbesondere im Vergleich zu komplexen Indizierungsmechanismen bei Arrays.
Flexibilität und Erweiterbarkeit: structs
bieten Flexibilität, da sie verschiedene Datentypen enthalten können. Dies ermöglicht die Definition komplexer Datenstrukturen, die leicht erweitert oder angepasst werden können, ohne den gesamten Code umzuschreiben. Dies ist besonders nützlich, wenn neue Daten hinzugefügt werden müssen.
Nachteile eines struct durch die öffentliche, einfache Struktur
Wo Vorteile sind, sind auch Nachteile. Daher ergeben sich aus dem sehr geöffneten Aufbau des struct folgende Nachteile.
Keine Methoden: Im Gegensatz zu Klassen in einigen Programmiersprachen können structs
keine Methoden enthalten. Das bedeutet, dass du keine Funktionen direkt an ein struct
binden kannst.
Begrenzte Vererbung: Im Vergleich zu Klassen bieten structs
eine begrenzte Vererbungsfähigkeit. Du kannst nur öffentliche Datenmitglieder erben, und es gibt keine Möglichkeit, den Zugriff zu steuern oder Funktionen zu überschreiben.
Keine Kontrollmechanismen: structs
bieten standardmäßig keinen Schutzmechanismus für ihre Datenmitglieder. Alle Daten sind standardmäßig öffentlich zugänglich, was potenzielle Probleme in Bezug auf Datenintegrität und -sicherheit verursachen kann.
Keine Zugriffsmodifikatoren: Anders als bei Klassen, bei denen du private, geschützte und öffentliche Zugriffsmodifikatoren verwenden kannst, haben structs
standardmäßig nur öffentlichen Zugriff. Das kann die Kontrolle über den Zugriff auf die Daten beeinträchtigen.