Junge Junge Junge Junge .... so gut hat es noch nie jemand erklärt ... Damit kann man auch gleich selber loslegen ... Vielen Dank .... bitte mehr von solchen Tutorials
Programmiere seit Jahren eigentlich nur mit Funktionen, aber durch Dich Frank ist mir jetzt erst der Nutzen von Klassen bewusst geworden. 👍 Super gerne mehr der Arduino Videos. 👍
Lieben Herzlichen DANK! Da hat ein „alter Mann“ einem „alten Mann“ das Leben, in Bezug auf Programmierverständnis, erleichtert. Nun verstehe ich das auch 😉🤗
Kurz zu den Begriffen "Klasse" vs. "Objekt": Klasse ist die abstrakte Beschreibung von Eigenschaften und Verhalten des neuen Typs den du da definierst (hier LedClass), Objekt ist dann eine konkrete Instanz dieser Klasse. In deinem Beispiel hast du drei konkrete LedClass-Objekte geschaffen und die waren vom Typ LedClass.
Super erklärt! Mit der LED Steuerung ist es auch viel übersichtlicher, als wenn man 3 bis 16 Schrittmotoren verwendet hätte. Da wären dann aber die eingesparten Codezeilen aufgefallen.
Super Video, perfekt erklärt. Für Anfänger ist es sehr hilfreich sich vorzustellen dass die in einer Klassen-Datei definierte Klasse nur ein Bauplan ist und dass die im normalen Programm-Code erstellten eigenständigen Instanzen dann die real existierenden und funktionierenden bzw. ansprechbare Objekte dieser in der Klasse definierten Idee darstellen. Hier sind es also drei eigenständige, total voneinander unabhängige Objekte die nach der Vorlage dieser Klasse gefertigt wurden und, ganz wichtig, auch immer nur einzeln unter Verwendung ihres eigenen Namens angesprochen werden können.
Danke für die gute Erklärung. Ist sehr gut verständlich. Für die Ausgabe über Seriell, hätte ich mit "sprintf" oder einer ähnlichen Funktion gearbeitet. So könnte man es ein bisschen übersichtlicher programmieren.
Wirklich super Videoidee, sehr gut rüber gebracht! In einen gut 15 Jahren Berufserfahrung ging es meistens um Embedded-Programmierung in C++. Natürlich würde ich im Arbeitsumfeld anders Programmieren, aber das war schon ein absolut super Einstieg. Evtl könnte man in nem Folge-Video auf constructor-Methode eingehen und in dem Zuge reparieren, dass die LEDs beim Start blinken. Man könnte auch eine Klasse schreiben die alle LEDs in einem Objekt behandelt... wobei dann könnte man auch funktional programmieren. 😇 Objekt orientierte Programmierung verbraucht oft (nicht immer) mehr Speicher (v.a. RAM) und Laufzeit als funktonale Programmierung... wenn's mal auf dem Arduino eng wird, sollte man überlegen ob man es mit den Klasen und Objekten übertrieben hat 😉 Bin das erste mal auf den Kanal aufmerksam geworden. Hab gerde einige interessante Videos entdeckt. Hab gleich mal nen Abo da gelassen.
Ich habe mehr als 20 Jahre berufsmäßig ausschließlich in C# programmiert, OOP ist also mein Metier. Vorher C++ und noch davor C. Aber nie irgendwas mit Arduino & Co. Ich war bis jetzt auch der Meinung, dass der Arduino "nur" in C programmiert werden kann. Ist das ein vollwertiges C++?
@@TheMicrofox HI, ich bin nicht 100% sicher ob wirklich alles aus C++ geht. Aber grundsätzlich basiert der compiler auf C++ 11. Also nicht gerade die neuste C++ Version. Ich arbeite mit C++ in embedded systemen seit ca 15 Jahren. Embedded Programmierung ist immer etwas speziell, weil man ganz schnell an die hardware limits kommt. Gerade wer massiv auf Vererbung setzt wird bei größeren Projekten feststellen, dass die ganzen look-up-tabellen ordentlich RAM und Laufzeit kosten können. Ich finde die Embedded-Welt super interessant, weil man direkter mit der "echten Welt" arbeitet. Das bringt ganz neue Komplexität in die Programme bei gleizeitiger Resourcen-Beschränkung. Ich finde es auch nach den ganzen Jahren einfach super spannend. Seit ich beruflich weniger zum Coden komme, tobe ich mich halt privat mit Arduino, ESP und Co aus. Ein riesen Spass den ich nur jedem begeisteren Programmier empfehlen kann.
Jau. Voll gut! Wenn ich nich immer trubbel mit der Hartware hätte würde ich mich warscheinlich auch öfters versuchen damit auseinander zu setzen.... Aber was nich is kann ja noch werden. Macht auf jeden Fall Laune auf mehr 👍
Hör mal, Video richtig gut erklärt würde mich über mehr solcher Videos freuen über Objektorientierung. ich übergebe gerne die Pins dem Konstruktor und lasse den Konstruktor auch den PIN Mode setzen
Ich schaue mal, ob das optisch passt wenn ich das ein bisschen größer mache. Beim nächsten Video. Aber so ein Video sollte man auch schon am Computer gucken, nicht auf dem Handy 😄
Schöne Erklärung! Danke, dass Du dieses Thema behandelst!! 👍👏👏👏 Eine Frage, warum deklarierst und definierst Du die 3 Boolsche Variablen zum Drücken der drei Taster eigentlich als GLOBALE Variablen und nicht LOKAL (auf dem Stack) in loop() Und wozu 3 Variablen, benötigst Du doch jede nur kurz einmal, nämlich um JEWEILS den Button Status abzufragen und um dann diese Info zu nutzen um zu reagieren - in Deinem Fall pro Button eben eine LED zu schalten. Also mein Tipp: Deklariere und definiere den Buttonstatus LOKAL (auf dem Stack) INNERHALB loop() und dann reicht eine Variable buttonPressed, die Du dann für alle drei Buttonabfragen nutzt. Zusätzlicher Nutzen: Variablendeklarationen auf dem Stack (lokale Variablen) verbrauchen im Gegensatz zu *globalen* Variablen keinen zus. Speicher weil sie auf dem ohnehin für den Stack reservierten Speicher temporär (solange der Stack Frame der Funktion aktiv ist)) angelegt werden. Eine globale Variable dagegen belegt den Speicher im RAM dauerhaft, weil sie ja global ist. ;-)
@@FrohnixBastelbude Nein, das glaube ich nicht. 🙄 Okay, ich habe vielleicht vergessen zu erwähnen, dass sich mein Hinweis auf den *alten Code* (noch ohne Anwendung der Klasseninstanzen) bezieht: 😐 Schau, bei 2:17 stellst Du die 3 booleans ja sogar noch prominent im Video vor! 😉 Konkret steht doch in den Zeilen 1 bis 3: bool button1 = false; // Variable zum Speichern des Zustands des ersten Tasters bool button2 = false; // Variable zum Speichern des Zustands des zweiten Tasters bool button3 = false; // Variable zum Speichern des Zustands des dritten Tasters Und dieser 3 Variablen deklarierst und definierst Du im global scope (das sagst Du ja auch @2:28 "Wie immer vor'm setup damit die immer im *ganzen* Programm gelten". Meine Frage: Warum müssen die im GANZEN Programm gelten? Wo benutzt Du sie denn sonst noch außer in der Funktion loop()? ...und in den Zeilen 20, 21, und 22 benutzt Du sie ja auch (sogar mit Deiner Erklärung @3:46). Und *genau* um *diese* 3 booleans geht es mir: Warum nutzt Du nicht EINE *lokale* bool variable (nicht 3(!)) um den Button (negiert) zuzuweisen um ihn dann zu benutzen um die jeweilige LED anzusteuern. Schließlich benutzt Du sie ja auch nur LOKAL und nicht mehr *Außerhalb des Scopes* (der Funktion)! Also wozu drei Variablen global deklarieren und unnötig Speicher verbraten. Ja, es sind nur 3 Bytes, aber hey... 😉 Wie gesagt "lokale" (auf dem Stack liegende) Variablen KOSTEN Dir keinen zusätzlichen Speicher. Nur TEMPORÄREN Stack Space. Und der wird am Ende des Scopes ja wieder vom Compiler (generierten Code) automatisch abgeräumt. Nutze doch diesen genialen Vorteil! Diesen Tipp wollte ich Dir / Euch nur geben.
@@FrohnixBastelbude Hahahaha Achso! Naja, so kann man es auch nennen! 😉 Die Sache ist nur, dass Du es später mit den Objekten es ja keinen Deut besser machst. Schau, Du führst @9:38 in der Klasse die Membervariable 'bool button" ein, die ja eigentlich überflüssig ist (siehe meinen Kommentar oben). Die anderen beiden Variablen sind freilich nötig, weil Du sie ja in den Methoden brauchst. Und DADURCH, dass Du dann später die 3 Objekte led1, led2 und led3 der Klasse LedPin *GLOBAL* erzeugst, legst Du *implizit* genau wieder jeweils diese (überflüssige) bool Variable global an! Dadurch, dass Du sie private macht schützt Du ja nur den Zugriff - wie Du es ja auch richtig sagst. Deren Speicher wird aber trotzdem angelegt. Und verschwendet also streng genommen genauso wie im "Negativbeispiel" globalen Stoage für drei Button Variablen. Halt _eingekapselt_ in die drei Objekte. Verstehst Du, was ich meine?
@@hanspeterbestandig2054 Ja, ok. Ich verschwende 1 Byte pro Objekt. Aber: ich programmiere bewusst so. Vorteile: 1. Konsistenz: Wenn der digitale Pin nur einmal pro Zyklus ausgelesen und das Ergebnis in einer boolschen Variable gespeichert wird, arbeiten alle Methoden innerhalb dieses Zyklus auf der gleichen Datenbasis. Das reduziert potenzielle Inkonsistenzen, wenn der Pin-Zustand sich schnell ändert. 2. Performance: digitalRead() wird nur einmal pro Zyklus aufgerufen, was die Anzahl der Hardwarezugriffe reduziert und somit effizienter ist. Bei häufigem Zugriff auf den Pin kann das entscheidend sein. 3. Bessere Strukturierung: Eine zentrale Methode zur Handhabung der Eingänge sorgt für eine klarere Trennung von Logik und Hardwarezugriff. Das macht den Code oft wartungsfreundlicher und sauberer. Nachteile: 1. Veraltete Daten: Die boolschen Attribute repräsentieren nur den Zustand des Pins zum Zeitpunkt des letzten Lesens. Zwischen zwei Lesezyklen könnte sich der Zustand geändert haben, was nicht sofort erfasst wird. 2. Speicheraufwand: Man benötigt zusätzliche boolsche Variablen, um den Zustand der Eingänge zu speichern. Nachteil 1 ist bekannt und kann somit eingeplant werden. Nachteil 2 nehme ich in Kauf, wegen Vorteil 1,2 &3 Natürlich ist das jetzt bei dem LED-Beispiel irrelevant, aber bei meinen Projekten bin ich auf eine konsistente Datenbasis angewiesen und dann gewöhnt man sich das an 😁 Hier noch einmal die Vor- und Nachteile eines direkten digitalRead ohne bollsche Variablen: Vorteile: 1.Einfachheit: Der Code ist unmittelbar und benötigt keine zusätzliche Verwaltung von boolschen Variablen. Jede Methode liest den aktuellen Zustand des Pins direkt. 2.Aktuelle Daten: Da der Pin bei jeder Methode neu ausgelesen wird, erhält man immer den aktuellen Zustand des digitalen Eingangs. Nachteile: 1.Wiederholter Aufruf von digitalRead(): Jedes Mal, wenn eine Methode aufgerufen wird, muss digitalRead() aufgerufen werden. Das kann bei häufigen Zugriffen (z. B. in jedem Durchlauf der loop()-Funktion) zu Performance-Einbußen führen, besonders bei Mikrocontrollern wie dem Arduino, wo ein digitalRead() im Mikrosekundenbereich liegt. 2.Inkonsistenz: Wenn mehrere Methoden in einer Klasse den digitalen Zustand abfragen, aber zu unterschiedlichen Zeitpunkten, könnten sie unterschiedliche Ergebnisse erhalten, wenn sich der Zustand des Pins zwischen den Aufrufen geändert hat. Das kann zu unerwarteten Zuständen und schwer nachvollziehbaren Fehlern führen. Klar sollte sein: Ein erzeugen der Objekte im loop ist speicher- und performancetechnisch der absolute overkill. Zumal die Objekte so keine Daten mehr halten können, weil sie nach jedem Durchlauf zerstört werden. Fazit: Für mich ist es wichtiger alle relevanten Zustände zentral zu erfassen, damit alle Methoden in diesem Erfassungszyklus mit der selben Datenbasis arbeiten, anstatt ein paar Byte Speicher zu sparen. Und noch einmal: Natürlich ist das, für das LED-Projekt, absolut irrelevant, aber ich zeige den Leuten lieber gleich, wie man es fehlerunanfälliger programmiert. Und Anfängerfreundlich (falls sich jetzt hier wieder ein studierter einklinken möchte, der die Klasse auf header- und cpp Dateien splitten will) Und ja, eigentlich hätte schon längst das Nachfolgevideo erscheinen sollen, wo ich, unter anderem, den Unterschied zwischen Klassen und Objekten erkläre, das Funktionen = Methoden sind und das Variablen in Klassen Attribute bzw. Felder heißen. Da macht nur leider gerade mein Job einen Strich durch die Rechnung 😏
Ich mag Deine Tutorials, super erklärt (wie auch die anderen Arduino-Videos) aber Du nutzt nur gute 25% des Bildschirms, die anderen fast 75 sind schwarz ohne Inhalt. Es ist schön, wenn man sieht was erklärt wird (Strg+Mausrad für die Schrifgröße). Sorry für die kleine Kritik 😊
Hallo Frank, wann läuft Dein Shop wieder ? Wann kommen die Neuen Blastgate raus ? Und was wird es noch so geben von Dir dieses Jahr ? Viel hat es ja fieses Jahr nicht gegeben
Bitte erlaube mir eine Erklärung zu 24:52, weil sie echt wichtig ist! *ACHTUNG* : KLASSEN sind *KEINE* OBJEKTE. Du musst die Begriffe *unbedingt* semantisch *trennen* ! 1) KLASSEN sind *Definitionen* (Baupläne / (aka Strukturen)), die man (freilich der Compiler) später *benutzt* um daraus OBJEKTE zu *erzeugen* ! 2) OBJEKTE dagegen werden (gemäß 1)) aus Klassen erzeugt. Man sagt auch, dass Objekte INSTANZEN von Klassen sind. Die OBJEKTE sind *KONKRET* denn sie belegen später den Speicher! NICHT die Klasse, weil sie eben nur die *Beschreibung* (Der Bauplan für den Compiler) ist! Stelle Dir eine *Klasse* als die *Beschreibung* (den Bauplan) vor, nach dem der Compiler dann beim INSTANZIIEREN dieser Klasse ein Objekt *erzeugt* . Beispiel: Es gibt eine *Klasse* Billardkugel, die beschreibt über welche Eigenschaften (Membervariablen und Zugriffsmethoden) jede Billdardkugel verfügen soll. Wichtig: Die Klasse selbst ist aber noch *keine* Billardkugel (noch nichts Konkretes im Speicher), sondern nur deren "Beschreibung" (deren Struktur)! So, Du möchtest nun aus dieser Klasse (dem Bauplan) 15 *konkrete* Billardkugeln erstellen. Also erzeugst Du eben die 15 Billardkugeln (oder auch 1000) - also OBJEKTE *von* der KLASSE (oder gleichbedeutend vom Typ) *Billardkugel*. So wie Du eben Deine drei Objekte led1, led2 und led3 auch von der Klasse 'LedClass' erzeugt hast. Also in einem Satz: led1, led2 und led3 sind OBJEKTE oder INSTANZEN der KLASSE LedClass. Und GENAU DIES macht Objektorientierte Programmierung ja so mächtig! Du erstellst einen Bauplan (Klasse) und kannst daraus beleibig (freilich nur so viel verfügbaren RAM Dein System hat) OBJEKTE davon erzeugen. Deswegen gibt es auch keine Kopien (@32:08) von Klassen, sondern nur von Objekten! Aber ich weiss, Du meinst hier nicht Kopien sondern die drei *Instanzen* der Klasse. Bitte verzeihe mir meine Pedanterie, aber es ist wichtig, die Begriffe klar zu trennen. Wenn es Dich tröstet: Ich (bin Embedded SW Entwickler) bilde oft auch Elektrotechnik und Informatik Studenten aus und auch die vermischen diese Begriffe gern obschon sie es eigentlich in ihren Vorlesungen in der Hochschule lernten.
sehr einsteigerfreundliches video. was mir persönlich fehlt: nicht nur rausarbeiten, wie einfach man mit der objektorientierten programmierung gemeinsamkeiten zusammenfassen kann, sondern wie einfach man auch unterschiede einarbeiten kann. das hätte man z.b. über eine konfigurierbare blinkdauer machen können, damit jede led (mit dem selben code in der klasse) anders oft blinkt. so ein bisschen ist das ja über den zähler und die unterschiedlichen pins je objekt-instanz drin, aber es wäre halt noch deutlicher möglich gewesen.
Schön erklärt, aber an den Begrifflichkeiten besteht Verbesserungsbedarf. Eine Klasse ist kein Objekt sondern eine Blaupause für ein Objekt. Ein Objekt entsteht erst beim Instanzieren einer Klasse. In Deinen Beispiel existiert nur eine Klasse, aber 3 Objekte. Das ist ein wichtiger und entscheidender Unterschied und sollte gerade Anfängern richtig vermittelt werden. Eine Klasse hat auch keine „Variablen“ und „Funktionen“, sondern „Eigenschaften“ und „Methoden“. Leider fehlt die Erwähnung von Konstruktoren, dann wird der Code noch kürzer und setPin() wird gar nicht benötigt. Das ist evtl. etwas für zukünftige Videos, dann bitte auch das Überladen von Konstruktoren und Methoden erklären. Als Krönung dann noch Vererbung und Schnittstellen (bzw. abstrakte Klassen in C++), damit kann OOP erst so richtig zeigen was es kann. Dann sollte man sich auch gleich angewöhnen die kleinstmöglichen Datentypen zu verwenden. Du verwendest z.B. int, wo es auch ein byte getan hätte. Das ist eine unnötige Verschwendung des RAM und CPU-Zeit, welches eh häufig knapp ist. Wenn man eine Klasse mit vielen Eigenschaften besitzt, und hunderte/tausende Instanzen erstellt, dann geht der RAM schnell zuneige;-)
Er ist halt kein Programmierer. Wenn man OOP wirklich gelernt hat ist es natürlich was anderes. Ich finde es dennoch gut wenn Anfänger durch Videos wie hier zumindest Mal angeleitet werden Klassen zu nutzen und Objekt orientiert zu programmieren.
Well, in order to understand Concepts of Software Development an ATMEGA among the GCC C++ Compiler that is used within the Arduino IDE is absolutely sufficient! Ever use the easy path to learn. not the hard way! These complex CPUs just distract you from the real intention!
Entschuldige bitte, aber ist das jetzt wirklich die Fortführung aus der Arduino Reihe wo der letzte Teil vor über 1 Jahr von dir erstellt wurde! Danke, aber wir sind schon weiter....!
5:43 - Ich bin seit fast 40 Jahren Software-Entwickler, aber ich habe ernsthaft noch nie eine if-Schleife gesehen. Kannst du dazu bitte mal ein Video erstellen?
Junge Junge Junge Junge .... so gut hat es noch nie jemand erklärt ... Damit kann man auch gleich selber loslegen ... Vielen Dank .... bitte mehr von solchen Tutorials
Hervorragend verständlich und gut formuliert. Besonders für Einsteiger schnell zu begreifen.
Das ist ein Video, welches Objekte endlich einmal für Jeden verständlich erklärt. Danke dafür
Programmiere seit Jahren eigentlich nur mit Funktionen, aber durch Dich Frank ist mir jetzt erst der Nutzen von Klassen bewusst geworden. 👍 Super gerne mehr der Arduino Videos. 👍
Lieben Herzlichen DANK! Da hat ein „alter Mann“ einem „alten Mann“ das Leben, in Bezug auf Programmierverständnis, erleichtert. Nun verstehe ich das auch 😉🤗
vielen vielen Dank, das du diese arduino videos machst. habe bis jetzt niemanden gefunden der dieses Thema so verständlich und interressant erklärt.
Kurz zu den Begriffen "Klasse" vs. "Objekt": Klasse ist die abstrakte Beschreibung von Eigenschaften und Verhalten des neuen Typs den du da definierst (hier LedClass), Objekt ist dann eine konkrete Instanz dieser Klasse. In deinem Beispiel hast du drei konkrete LedClass-Objekte geschaffen und die waren vom Typ LedClass.
Super erklärt!
Mit der LED Steuerung ist es auch viel übersichtlicher, als wenn man 3 bis 16 Schrittmotoren verwendet hätte. Da wären dann aber die eingesparten Codezeilen aufgefallen.
Super Video, perfekt erklärt. Für Anfänger ist es sehr hilfreich sich vorzustellen dass die in einer Klassen-Datei definierte Klasse nur ein Bauplan ist und dass die im normalen Programm-Code erstellten eigenständigen Instanzen dann die real existierenden und funktionierenden bzw. ansprechbare Objekte dieser in der Klasse definierten Idee darstellen. Hier sind es also drei eigenständige, total voneinander unabhängige Objekte die nach der Vorlage dieser Klasse gefertigt wurden und, ganz wichtig, auch immer nur einzeln unter Verwendung ihres eigenen Namens angesprochen werden können.
Genau so musst du dir das vorstellen. So kann man wahre Objektmonster erstellen, die Im Hauptloop nur wenige Zeilen darstellen.
Hallo Frank, wieder mal super erklärt, gerne mehr davon… LG Werner
Danke! Super gut erklärt! Jetzt noch der Brückenschlag zu den .cpp Files :)
Hy Frank, klasse wie du das erklärst ... total gut und verständlich. Gerne mehr. 😊
Super Video, bitte mach mit Objektorientierung weiter 😊
Wow 👍👍👍 MEGA!!! 🤩🤩🤩 Ein wirklich beeindruckendes Tutorial. Auch ich wünsche mir mehr davon.
Super Erklärt kann ich gebrauchen. Danke für's Video bitte mehr von den Video's
Hi, schön das die Serie weiter geht, klasse erklärt, gerne mehr davon :)
Danke für die gute Erklärung. Ist sehr gut verständlich.
Für die Ausgabe über Seriell, hätte ich mit "sprintf" oder einer ähnlichen Funktion gearbeitet. So könnte man es ein bisschen übersichtlicher programmieren.
Super. Jetzt hab ich endlich das Thema Klassen verstanden.
Danke für die sehr gute Erklärung. Ich werde das jetzt auch versuchen und für meine Projekte einsetzen.
Hallo Frank, vielen Dank für dieses Video, super erklärt.
_Absolut top erklärt, schönes Video._
krass wie einfach man sich das machen kann :-) Danke
Wirklich super Videoidee, sehr gut rüber gebracht!
In einen gut 15 Jahren Berufserfahrung ging es meistens um Embedded-Programmierung in C++. Natürlich würde ich im Arbeitsumfeld anders Programmieren, aber das war schon ein absolut super Einstieg. Evtl könnte man in nem Folge-Video auf constructor-Methode eingehen und in dem Zuge reparieren, dass die LEDs beim Start blinken.
Man könnte auch eine Klasse schreiben die alle LEDs in einem Objekt behandelt... wobei dann könnte man auch funktional programmieren. 😇
Objekt orientierte Programmierung verbraucht oft (nicht immer) mehr Speicher (v.a. RAM) und Laufzeit als funktonale Programmierung... wenn's mal auf dem Arduino eng wird, sollte man überlegen ob man es mit den Klasen und Objekten übertrieben hat 😉
Bin das erste mal auf den Kanal aufmerksam geworden. Hab gerde einige interessante Videos entdeckt. Hab gleich mal nen Abo da gelassen.
Ich habe mehr als 20 Jahre berufsmäßig ausschließlich in C# programmiert, OOP ist also mein Metier.
Vorher C++ und noch davor C.
Aber nie irgendwas mit Arduino & Co.
Ich war bis jetzt auch der Meinung, dass der Arduino "nur" in C programmiert werden kann.
Ist das ein vollwertiges C++?
@@TheMicrofox HI, ich bin nicht 100% sicher ob wirklich alles aus C++ geht. Aber grundsätzlich basiert der compiler auf C++ 11. Also nicht gerade die neuste C++ Version.
Ich arbeite mit C++ in embedded systemen seit ca 15 Jahren. Embedded Programmierung ist immer etwas speziell, weil man ganz schnell an die hardware limits kommt. Gerade wer massiv auf Vererbung setzt wird bei größeren Projekten feststellen, dass die ganzen look-up-tabellen ordentlich RAM und Laufzeit kosten können.
Ich finde die Embedded-Welt super interessant, weil man direkter mit der "echten Welt" arbeitet. Das bringt ganz neue Komplexität in die Programme bei gleizeitiger Resourcen-Beschränkung. Ich finde es auch nach den ganzen Jahren einfach super spannend. Seit ich beruflich weniger zum Coden komme, tobe ich mich halt privat mit Arduino, ESP und Co aus. Ein riesen Spass den ich nur jedem begeisteren Programmier empfehlen kann.
Jau. Voll gut! Wenn ich nich immer trubbel mit der Hartware hätte würde ich mich warscheinlich auch öfters versuchen damit auseinander zu setzen.... Aber was nich is kann ja noch werden.
Macht auf jeden Fall Laune auf mehr 👍
Sind Sie sich sicher, dass es immer Hardwareprobleme sind? Oder vielleicht auch die Software nicht so mit der Hardware spielen mag? 🙄
Bitte mehr davon 🥰
Super Video 👍
Gerne mehr davon!
Danke
Sehr interessant und hilfreich 😊
Tolle Erklärung
DANKE ❤
Hör mal, Video richtig gut erklärt würde mich über mehr solcher Videos freuen über Objektorientierung. ich übergebe gerne die Pins dem Konstruktor und lasse den Konstruktor auch den PIN Mode setzen
Ganz gut erklärt, danke
super erklärt. Vielen Dank. Könntest du noch ein Tutorial über den s.g Konstruktor in einer Klasse machen.
... ganz ausgezeichnet gemacht und erklärt
Geniales Video
Klasse erkärt !!!
Hier sogar wörtlich genommen.
Genial, mehr davon!
genial erklärt ; danke
Das war ja Klasse .....
Klasse, wie Du die Klassen progammierst Frank! 🤣👍
Sorry, ich kann einfach an flachen Wortspielen nicht vorbeigehen.
Cooles Video.
🤣
TOP
Schön erklärt, aber noch schöner wäre, wenn das was du schreibst nicht so klein in der Ecke stünde, sondern gezoomt wäre, dass man mitlesen kann.
Ich schaue mal, ob das optisch passt wenn ich das ein bisschen größer mache. Beim nächsten Video. Aber so ein Video sollte man auch schon am Computer gucken, nicht auf dem Handy 😄
Schöne Erklärung! Danke, dass Du dieses Thema behandelst!! 👍👏👏👏
Eine Frage, warum deklarierst und definierst Du die 3 Boolsche Variablen zum Drücken der drei Taster eigentlich als GLOBALE Variablen und nicht LOKAL (auf dem Stack) in loop() Und wozu 3 Variablen, benötigst Du doch jede nur kurz einmal, nämlich um JEWEILS den Button Status abzufragen und um dann diese Info zu nutzen um zu reagieren - in Deinem Fall pro Button eben eine LED zu schalten. Also mein Tipp: Deklariere und definiere den Buttonstatus LOKAL (auf dem Stack) INNERHALB loop() und dann reicht eine Variable buttonPressed, die Du dann für alle drei Buttonabfragen nutzt.
Zusätzlicher Nutzen: Variablendeklarationen auf dem Stack (lokale Variablen) verbrauchen im Gegensatz zu *globalen* Variablen keinen zus. Speicher weil sie auf dem ohnehin für den Stack reservierten Speicher temporär (solange der Stack Frame der Funktion aktiv ist)) angelegt werden. Eine globale Variable dagegen belegt den Speicher im RAM dauerhaft, weil sie ja global ist. ;-)
Wo deklariere ich 3 boolsche Variablen? Ich glaube, du hast gerade ein anderes Programm vor dir...
@@FrohnixBastelbude Nein, das glaube ich nicht. 🙄 Okay, ich habe vielleicht vergessen zu erwähnen, dass sich mein Hinweis auf den *alten Code* (noch ohne Anwendung der Klasseninstanzen) bezieht: 😐
Schau, bei 2:17 stellst Du die 3 booleans ja sogar noch prominent im Video vor! 😉
Konkret steht doch in den Zeilen 1 bis 3:
bool button1 = false; // Variable zum Speichern des Zustands des ersten Tasters
bool button2 = false; // Variable zum Speichern des Zustands des zweiten Tasters
bool button3 = false; // Variable zum Speichern des Zustands des dritten Tasters
Und dieser 3 Variablen deklarierst und definierst Du im global scope (das sagst Du ja auch @2:28 "Wie immer vor'm setup damit die immer im *ganzen* Programm gelten". Meine Frage: Warum müssen die im GANZEN Programm gelten? Wo benutzt Du sie denn sonst noch außer in der Funktion loop()?
...und in den Zeilen 20, 21, und 22 benutzt Du sie ja auch (sogar mit Deiner Erklärung @3:46).
Und *genau* um *diese* 3 booleans geht es mir: Warum nutzt Du nicht EINE *lokale* bool variable (nicht 3(!)) um den Button (negiert) zuzuweisen um ihn dann zu benutzen um die jeweilige LED anzusteuern. Schließlich benutzt Du sie ja auch nur LOKAL und nicht mehr *Außerhalb des Scopes* (der Funktion)!
Also wozu drei Variablen global deklarieren und unnötig Speicher verbraten. Ja, es sind nur 3 Bytes, aber hey... 😉 Wie gesagt "lokale" (auf dem Stack liegende) Variablen KOSTEN Dir keinen zusätzlichen Speicher. Nur TEMPORÄREN Stack Space. Und der wird am Ende des Scopes ja wieder vom Compiler (generierten Code) automatisch abgeräumt. Nutze doch diesen genialen Vorteil! Diesen Tipp wollte ich Dir / Euch nur geben.
@@hanspeterbestandig2054 Das ist doch das "Negativbeispiel"
@@FrohnixBastelbude Hahahaha Achso! Naja, so kann man es auch nennen! 😉
Die Sache ist nur, dass Du es später mit den Objekten es ja keinen Deut besser machst. Schau, Du führst @9:38 in der Klasse die Membervariable 'bool button" ein, die ja eigentlich überflüssig ist (siehe meinen Kommentar oben). Die anderen beiden Variablen sind freilich nötig, weil Du sie ja in den Methoden brauchst. Und DADURCH, dass Du dann später die 3 Objekte led1, led2 und led3 der Klasse LedPin *GLOBAL* erzeugst, legst Du *implizit* genau wieder jeweils diese (überflüssige) bool Variable global an!
Dadurch, dass Du sie private macht schützt Du ja nur den Zugriff - wie Du es ja auch richtig sagst. Deren Speicher wird aber trotzdem angelegt. Und verschwendet also streng genommen genauso wie im "Negativbeispiel" globalen Stoage für drei Button Variablen. Halt _eingekapselt_ in die drei Objekte. Verstehst Du, was ich meine?
@@hanspeterbestandig2054 Ja, ok. Ich verschwende 1 Byte pro Objekt.
Aber: ich programmiere bewusst so.
Vorteile:
1. Konsistenz: Wenn der digitale Pin nur einmal pro Zyklus ausgelesen und das Ergebnis in einer boolschen Variable gespeichert wird, arbeiten alle Methoden innerhalb dieses Zyklus auf der gleichen Datenbasis. Das reduziert potenzielle Inkonsistenzen, wenn der Pin-Zustand sich schnell ändert.
2. Performance: digitalRead() wird nur einmal pro Zyklus aufgerufen, was die Anzahl der Hardwarezugriffe reduziert und somit effizienter ist. Bei häufigem Zugriff auf den Pin kann das entscheidend sein.
3. Bessere Strukturierung: Eine zentrale Methode zur Handhabung der Eingänge sorgt für eine klarere Trennung von Logik und Hardwarezugriff. Das macht den Code oft wartungsfreundlicher und sauberer.
Nachteile:
1. Veraltete Daten: Die boolschen Attribute repräsentieren nur den Zustand des Pins zum Zeitpunkt des letzten Lesens. Zwischen zwei Lesezyklen könnte sich der Zustand geändert haben, was nicht sofort erfasst wird.
2. Speicheraufwand: Man benötigt zusätzliche boolsche Variablen, um den Zustand der Eingänge zu speichern.
Nachteil 1 ist bekannt und kann somit eingeplant werden.
Nachteil 2 nehme ich in Kauf, wegen Vorteil 1,2 &3
Natürlich ist das jetzt bei dem LED-Beispiel irrelevant, aber bei meinen Projekten bin ich auf eine konsistente Datenbasis angewiesen und dann gewöhnt man sich das an 😁
Hier noch einmal die Vor- und Nachteile eines direkten digitalRead ohne bollsche Variablen:
Vorteile:
1.Einfachheit: Der Code ist unmittelbar und benötigt keine zusätzliche Verwaltung von boolschen Variablen. Jede Methode liest den aktuellen Zustand des Pins direkt.
2.Aktuelle Daten: Da der Pin bei jeder Methode neu ausgelesen wird, erhält man immer den aktuellen Zustand des digitalen Eingangs.
Nachteile:
1.Wiederholter Aufruf von digitalRead(): Jedes Mal, wenn eine Methode aufgerufen wird, muss digitalRead() aufgerufen werden. Das kann bei häufigen Zugriffen (z. B. in jedem Durchlauf der loop()-Funktion) zu Performance-Einbußen führen, besonders bei Mikrocontrollern wie dem Arduino, wo ein digitalRead() im Mikrosekundenbereich liegt.
2.Inkonsistenz: Wenn mehrere Methoden in einer Klasse den digitalen Zustand abfragen, aber zu unterschiedlichen Zeitpunkten, könnten sie unterschiedliche Ergebnisse erhalten, wenn sich der Zustand des Pins zwischen den Aufrufen geändert hat. Das kann zu unerwarteten Zuständen und schwer nachvollziehbaren Fehlern führen.
Klar sollte sein: Ein erzeugen der Objekte im loop ist speicher- und performancetechnisch der absolute overkill. Zumal die Objekte so keine Daten mehr halten können, weil sie nach jedem Durchlauf zerstört werden.
Fazit: Für mich ist es wichtiger alle relevanten Zustände zentral zu erfassen, damit alle Methoden in diesem Erfassungszyklus mit der selben Datenbasis arbeiten, anstatt ein paar Byte Speicher zu sparen.
Und noch einmal: Natürlich ist das, für das LED-Projekt, absolut irrelevant, aber ich zeige den Leuten lieber gleich, wie man es fehlerunanfälliger programmiert.
Und Anfängerfreundlich (falls sich jetzt hier wieder ein studierter einklinken möchte, der die Klasse auf header- und cpp Dateien splitten will)
Und ja, eigentlich hätte schon längst das Nachfolgevideo erscheinen sollen, wo ich, unter anderem, den Unterschied zwischen Klassen und Objekten erkläre, das Funktionen = Methoden sind und das Variablen in Klassen Attribute bzw. Felder heißen. Da macht nur leider gerade mein Job einen Strich durch die Rechnung 😏
Ich mag Deine Tutorials, super erklärt (wie auch die anderen Arduino-Videos) aber Du nutzt nur gute 25% des Bildschirms, die anderen fast 75 sind schwarz ohne Inhalt. Es ist schön, wenn man sieht was erklärt wird (Strg+Mausrad für die Schrifgröße).
Sorry für die kleine Kritik 😊
Hallo Frank,
wann läuft Dein Shop wieder ?
Wann kommen die Neuen Blastgate raus ?
Und was wird es noch so geben von Dir dieses Jahr ?
Viel hat es ja fieses Jahr nicht gegeben
Bitte erlaube mir eine Erklärung zu 24:52, weil sie echt wichtig ist!
*ACHTUNG* : KLASSEN sind *KEINE* OBJEKTE. Du musst die Begriffe *unbedingt* semantisch *trennen* !
1) KLASSEN sind *Definitionen* (Baupläne / (aka Strukturen)), die man (freilich der Compiler) später *benutzt* um daraus OBJEKTE zu *erzeugen* !
2) OBJEKTE dagegen werden (gemäß 1)) aus Klassen erzeugt. Man sagt auch, dass Objekte INSTANZEN von Klassen sind. Die OBJEKTE sind *KONKRET* denn sie belegen später den Speicher! NICHT die Klasse, weil sie eben nur die *Beschreibung* (Der Bauplan für den Compiler) ist!
Stelle Dir eine *Klasse* als die *Beschreibung* (den Bauplan) vor, nach dem der Compiler dann beim INSTANZIIEREN dieser Klasse ein Objekt *erzeugt* .
Beispiel: Es gibt eine *Klasse* Billardkugel, die beschreibt über welche Eigenschaften (Membervariablen und Zugriffsmethoden) jede Billdardkugel verfügen soll.
Wichtig: Die Klasse selbst ist aber noch *keine* Billardkugel (noch nichts Konkretes im Speicher), sondern nur deren "Beschreibung" (deren Struktur)!
So, Du möchtest nun aus dieser Klasse (dem Bauplan) 15 *konkrete* Billardkugeln erstellen. Also erzeugst Du eben die 15 Billardkugeln (oder auch 1000) - also OBJEKTE *von* der KLASSE (oder gleichbedeutend vom Typ) *Billardkugel*. So wie Du eben Deine drei Objekte led1, led2 und led3 auch von der Klasse 'LedClass' erzeugt hast.
Also in einem Satz: led1, led2 und led3 sind OBJEKTE oder INSTANZEN der KLASSE LedClass.
Und GENAU DIES macht Objektorientierte Programmierung ja so mächtig! Du erstellst einen Bauplan (Klasse) und kannst daraus beleibig (freilich nur so viel verfügbaren RAM Dein System hat) OBJEKTE davon erzeugen.
Deswegen gibt es auch keine Kopien (@32:08) von Klassen, sondern nur von Objekten! Aber ich weiss, Du meinst hier nicht Kopien sondern die drei *Instanzen* der Klasse.
Bitte verzeihe mir meine Pedanterie, aber es ist wichtig, die Begriffe klar zu trennen. Wenn es Dich tröstet: Ich (bin Embedded SW Entwickler) bilde oft auch Elektrotechnik und Informatik Studenten aus und auch die vermischen diese Begriffe gern obschon sie es eigentlich in ihren Vorlesungen in der Hochschule lernten.
sehr einsteigerfreundliches video. was mir persönlich fehlt: nicht nur rausarbeiten, wie einfach man mit der objektorientierten programmierung gemeinsamkeiten zusammenfassen kann, sondern wie einfach man auch unterschiede einarbeiten kann. das hätte man z.b. über eine konfigurierbare blinkdauer machen können, damit jede led (mit dem selben code in der klasse) anders oft blinkt. so ein bisschen ist das ja über den zähler und die unterschiedlichen pins je objekt-instanz drin, aber es wäre halt noch deutlicher möglich gewesen.
Das war erst der Einstieg. Es wird noch umfangreicher, keine „Angst“ 😀
ab 1:50 bildlicher Aufbau.
Danke
Ginge aber mit einer Funktion ebenso einfach, oder?
Das habe ich auch gedacht. Vielleicht erst der Anfang…
Ok, gilt natürlich nur für das einfache Beispiel.
Schön erklärt, aber an den Begrifflichkeiten besteht Verbesserungsbedarf.
Eine Klasse ist kein Objekt sondern eine Blaupause für ein Objekt.
Ein Objekt entsteht erst beim Instanzieren einer Klasse.
In Deinen Beispiel existiert nur eine Klasse, aber 3 Objekte. Das ist ein wichtiger und entscheidender Unterschied und sollte gerade Anfängern richtig vermittelt werden.
Eine Klasse hat auch keine „Variablen“ und „Funktionen“, sondern „Eigenschaften“ und „Methoden“.
Leider fehlt die Erwähnung von Konstruktoren, dann wird der Code noch kürzer und setPin() wird gar nicht benötigt.
Das ist evtl. etwas für zukünftige Videos, dann bitte auch das Überladen von Konstruktoren und Methoden erklären.
Als Krönung dann noch Vererbung und Schnittstellen (bzw. abstrakte Klassen in C++), damit kann OOP erst so richtig zeigen was es kann.
Dann sollte man sich auch gleich angewöhnen die kleinstmöglichen Datentypen zu verwenden. Du verwendest z.B. int, wo es auch ein byte getan hätte. Das ist eine unnötige Verschwendung des RAM und CPU-Zeit, welches eh häufig knapp ist.
Wenn man eine Klasse mit vielen Eigenschaften besitzt, und hunderte/tausende Instanzen erstellt, dann geht der RAM schnell zuneige;-)
Er ist halt kein Programmierer. Wenn man OOP wirklich gelernt hat ist es natürlich was anderes. Ich finde es dennoch gut wenn Anfänger durch Videos wie hier zumindest Mal angeleitet werden Klassen zu nutzen und Objekt orientiert zu programmieren.
What about blue pill (STM32) 🤓
Rather not, what may still come is the new UNO and the ESP32.
Well, in order to understand Concepts of Software Development an ATMEGA among the GCC C++ Compiler that is used within the Arduino IDE is absolutely sufficient! Ever use the easy path to learn. not the hard way! These complex CPUs just distract you from the real intention!
pinMode(jumpcut, LOW)....
Der Videoinhalt in allen Ehren, aber den Titel "Objekte" und das Titelbild "ein Frau" kann man auch falsch verstehen.. 😅
Entschuldige bitte, aber ist das jetzt wirklich die Fortführung aus der Arduino Reihe wo der letzte Teil vor über 1 Jahr von dir erstellt wurde! Danke, aber wir sind schon weiter....!
5:43 - Ich bin seit fast 40 Jahren Software-Entwickler, aber ich habe ernsthaft noch nie eine if-Schleife gesehen. Kannst du dazu bitte mal ein Video erstellen?
if Schleife, arghhh, bitte nicht... Ansonsten gut erklärt, vielen Dank.
Könntest du kurz den Grund erklären? Lese öfter delay ( da verstehe ich auch warum man es nicht nutzen sollte) aber warum If?
Haggebutton...😹
If Else Kling älter als 76 then Button 1 ufff
If Else Kling jünger wie elaubt...
Then Knast 🤫
Wie üblich ein klasse Video. 👍
Wer ist denn das hübsche Mädchen auf dem Daumennagelbild? 🥰
Ist bei Pixar rausgeflogen und brauchte Geld.