Gleichzeitiges Ansteuern mehrerer Aktionen (LED, Servos) via Klassen?

  • Hallo Thomas,


    ja, Du brauchst einen Zeittakt, der den nächsten Schritt auslöst. Eine solche Klasse brauch mindestens zwei Funktionen: die Startfunktion wird nur einmal aufgerufen und die Schrittfunktion so oft wie möglich. Das Video, das am kommenden Donnerstag (25.03.2021) erscheint zeigt das anhand einer Klasse mit 2 Leds und einem Taster. Inzwischen solltest Du Dir auch Video 45 anschauen. Dort wird das Prinzip genauer erklärt.


    Glücklicherweise ist die von Dir verwendete getKey() - Funktion nicht blockierend, so dass Du Dich nur noch um die Aktionen kümmern musst.


    Gruss

    René

  • Hallo René,


    ich habe mir Deine Videos angeschaut und auch weitestgehend verstanden.

    Allerdings bin ich damit mit meinem Problem nicht wirklich weitergekommen.

    Ich nehme an, ich muss meine Funktionsaufrufe in kleinste Abschnitte aufteilen (?). Ist dazu eine Funktion wie Dein tic() hilfreich?


    Gruß

    Thomas

  • Hallo René,


    vielen Dank schon mal soweit.

    Ich werde Deine genannten Videos gleich studieren.

    Bei keypad.h. handelt es sich um die Version 3.1.1 von Mark Stanley und Alexander Brevig. Ich hoffe, das hilft Dir weiter.


    Gruß

    Thomas

  • Hallo Thomas,


    das Programm ist auch schon in dieser Kurzversion recht komplex. Das Hauptproblem ist aber schon ersichtlich. Du hast zwar sehr schön das blockierende delay() vermieden, die meisten deiner anderen Funktionen sind aber blockierend. Es ist wirklich so, die drei Funktionen in der Funktion AufrufderFunktion werden nacheinander abgearbeitet. Daher darf keine der aufgerufenen Funktionen längere Zeit verbrauchen. Es ist also nicht erlaubt, beim Aufruf von Servobewegung() zu warten, bis der Servo seine Position erreich hat. Eine eigene Klasse für den Servo wäre sinnvoll. Vielleicht helfen dir die Videos 35 bis 37 aus der Reihe 'Der einfache Einstieg in Arduino & Co.' weiter. Dort wird ein Beispiel mit einem Servo gezeigt.


    Ich muss mich aber zuerst noch etwas damit beschäftigen, bevor ich einen brauchbaren Vorschlag machen kann.


    Woher hast du Keypad.h? Die Hauptfrage ist, ob myKepad.getKey() blockierend ist. Ideal wäre, wenn getKey() einfach 0 zurückgeben würde, wenn keine Taste gedrückt ist.


    Gruss

    René

  • Hallo Nicole und René,


    zuallererst einmal vielen Dank für Eure schnelle und freundliche Reaktion.

    Klar stelle ich Euch gerne meinen Code hier ein. Es handelt sich um eine Kurzversion des geplanten "großen" Codes.

    Ich habe hier eine Steuerung für die "Schreinerei Holzwurm" begonnen, in der ich in der Endversion vier Servos und drei LED's ansteuern will, deshalb nutze ich hier auch nur einen Arduino Uno.

    In meiner Funktion "Servobewegung" habe ich noch einen Fehler, die stoppt nicht nach dem geplanten Zeitraum, aber das ist nur ein Nebengeräusch.

    Ich bin gespannt auf Eure Vorschläge.


    Viele Grüße

    Thomas

  • Hallo Thomas,


    es gibt keine blöden Fragen :).


    Wenn man so viele Aufgaben wie Du es vor hast lösen möchte, macht es Sinn das ganze Stück für Stück anzugehen.

    Somit kann man am Ende wenn alles funktioniert den ganzen Code zusammenfügen.


    Wie René schon geschrieben hat, wäre es gut wenn Du deinen Code zeigen könntest.

    Somit kann man viel schneller sehen wo das Problem liegen könnte ?


    Auch ist der Serial Monitor eine große Hilfe um Fehler im Code zu finden.


    Viele Grüße

    Nicole

  • Hallo Thomas,


    delay() ist leider nicht die einzige Möglichkeit, den Programmablauf zu blockieren. Der Arduino kann grundsätzlich die Programme nur sequenziell abarbeiten. Wir müssen also quasi mit Tricks dafür sorgen, dass es von aussen wie parallele Abläufe aussieht. Und das kannn wirklich manchmal trickreich sein.

    Klassen sind kein Wundermittel. Sie helfen unter Umständen das Programm übersichtlicher zu gestalten. Das eigentliche Kernproblem lösen sie nicht direkt. Welche Klassenstruktur du dabei aufbaust, ist weitgehend dir überlassen. Das ist ein Thema, über das man stundenlang streiten könnte. Jeder hat so seine Vorlieben.


    Klassen eignen sich besonders für Vorgänge, die länger dauern. Diese kannst du nicht an einem Stück abarbeiten. Darum musst du zwischendurch unterbrechen und dann später wieder an der richtigen Stelle weitermachen. Da hat die Klasse den Vorteil, dass sie alle notwendigen Informationen dazu selbst speichern kann.


    Ich weiss, diese allgemeinen Informationen sind nicht besonders hilfreich. Deshalb empfehle ich dir, deinen Code hier hochzuladen. Dann kann ich gezielt Tipps zu Verbesserungsmöglichkeiten abgeben. Es muss auch nicht der ganze Code sein, ein Beispiel wo man sieht, dass es 'klemmt' genügt auch. Der Code sollte aber so vollständig sein, dass er übersetzt werden kann.


    Gruss

    René

  • Lieber René, liebe Community,


    ich habe eine für mich spezielle Herausforderung, die möglicherweise hier in der Community bereits besprochen wurde, allerdings fehlt mir offensichtlich die notwendige Fantasie, um den richtigen Suchbegriff zu finden.

    Ich möchte auf einem Modul meiner Modelleisenbahn diverse Aktionen mittels Arduino steuern. Es handelt sich dabei überwiegend um LED's, Servos, aber auch um Gleichstrommotoren und Relais, eventuell später sogar um einen Schrittmotor. Diese Aktionen möchte ich mit Hilfe eines Keypad an meinem Schaltpult ansteuern. Dabei sollen verschiedene Aktionen parallel ablaufen. Also zum Beispiel: Ich drücke "01#" auf dem Keypad und eine erste Leuchtdiode leuchtet für einen gewissen Zeitraum; ich drücke "02#" und eine zweite Leuchtdiode fängt parallel zur ersten LED an zu blinken; bei "03#" steuert ein Servo eine Figur an, die sich gleichzeitig auf der Anlage bewegt, usw. Diese Aktionen sollen natürlich alle gleichzeitig ablaufen können. Insgesamt habe ich auf dem Modul ca. 30 verschiedene solcher Aktionen installiert, weshalb ich einen Arduino Mega einsetzen möchte.


    In meiner Blauäugigkeit habe ich begonnen, einen Sketch zu schreiben, in dem ich mein Keypad installiere und auslese und dann je nach Tastenkombination eine bestimmte Funktion aufrufe, also z.B. "LEDBlinker", "Servobewegung" usw. Ich habe in diesen Funktionen auch grundsätzlich mit millis() gearbeitet und habe delay() komplett vermieden.

    Allerdings musste ich bei meinen ersten Versuchen feststellen, dass die Funktionen sich dann leider gegenseitig blockieren und nur nacheinander abgearbeitet werden, was ja nicht in meinem Sinn ist.


    Lange Vorrede, aber jetzt kommt meine Frage: Ist es hilfreich, wenn ich an dieser Stelle mit Klassen arbeite? Sollte ich dann verschiedene Klassen einrichten, eine für die LED-Funktionen, eine für die Servomotoren, etc oder besser eine Klasse für alle geplanten Aktionen? Und wie strukturiere ich diese Klassen am besten?


    Ich hoffe, meine Frage ist einigermaßen verständlich und auch nicht allzu blöd. Ich stehe in Sachen Arduino noch ziemlich am Anfang, habe aber vor vielen, vielen Jahren einige Erfahrung mit diversen Programmiersprachen gemacht und möchte altes Wissen jetzt auf einen aktuellen Stand bringen.

    Vielen Dank schon mal im Voraus

    Thomas