Modellbahnaktionen steuern.

  • Weil ich gerade mal Lust dazu hatte, habe ich versucht, den Programmcode (die Funktion "moveServo()") noch etwas zu verkürzen.


    Dabei ist folgendes herausgekommen:



    Tatsächlich macht diese Funktion das gleiche wie die "lange" Version mit den vier Einzelschleifen. Diese ist aber wesentlich kryptischer zu lesen. Man man braucht schon ein bisschen, um zu verstehen was da steht. ABER, obwohl diese Funktion kürzer ist, spart sie kaum Speicherplatz ein.

    Der verbrauche RAM war um 6 Byte größer (erklärbar, weil mehr Variablen verwendet werden) und Flash Speicherplatz nur 22 Byte kleiner.


    Was kann daraus gelernt werden?


    - Es ist gut, einfach lesbaren Code zu produzieren und lieber ein paar Zeilen mehr zu schreiben, weil durch eine bessere Verständlichkeit auch Fehler vermieden werden.

    - Verkürzen nur, wenn es nicht zu kryptisch wird, es wirklich spürbare Einsparungen oder Verbesserungen ergibt und/oder es sich als notwendig erweist.


    Jetzt kommt wieder ein "aber":


    Mit der kurzen Variante können fast beliebige Schritte eingestellt werden, indem man das Array "degreeArray" und die Variable "stepSize" anpasst.

    Will man z.B. statt 90° nur 45° Schritte machen, braucht man nur den Code in

    byte degreeArray[] = {0 ,45, 90, 135, 180, 135, 90, 45,0};

    byte stepSize = 45;

    ändern und fertig. In der ursprünglichen Variante müssten die Schleifen acht mal geschrieben werden, was wesentlich komplizierter wäre.

    Von daher wieder bedeutender ein Vorteil. In dieser Variante wäre die Speicherplatzersparnis deutlich.


    Das hat jetzt mit der Eingangsfrage nur bedingt etwas zu tun, aber ich war erst einmal etwas erstaunt, dass die kurze Variante nur recht wenig Speichereinsparung gebracht hat. Offenbar optimiert der Compiler schon eine ganze Menge. Und wo ich schon mal dabei war, dachte ich mir, ich schreibe mal etwas über das für und wieder bestimmter Entscheidungen, die man beim Programmieren so zu treffen hat.


    Vielleicht hat ja auch jemand noch eine elegantere/flexiblere Variante für diese moveServo Funktion und mag sie hier zeigen.


    Gruß Kai


    PS: Ergänzung - Weil ich schon mal dabei war habe ich das Programm dahingehend erweitert, dass wenn an PIN7 ein Status-LED angeschlossen wird (Vorwiderstand nicht vergessen), leuchtet diese so lange, bis die "moveServo()" Funktion abgeschlossen ist. Dadurch bekommt man noch eine optische Rückmeldung.


    42D4356B-6A82-4987-BAC0-657CE013D2F1.jpeg

  • Stimmt das hatte ich nicht bedacht das der servo ja wieder in Ausgangsposition muss da er ja sonst beim starten mit voller Power in diese läuft.


    Die Videos bin ich mittlerweile schon am auswendig lernen, beim verstehen selbiger eckt es einfach noch aber wie gesagt bin ja ganz neu im Thema.


    ich sag nochmal vielen lieben Dank du hast mir sehr geholfen.

  • Es steht in der Beschreibung ... die Funktion dauert bei einem Durchlauf etwa 4 * 90 * 14ms + 5 * 3000ms = 20040 ms (ohne die Zeit welche der Mikrocontroller braucht, um die Befehle zu verarbeiten - das vernachlässigen wir mal). Drei mal ca. 20 Sekunden ergibt eine Minute. So wolltest Du es doch.


    Ich denke, das Hin- und Herfahren des Servos ist ein kompletter Vorgang, der durchlaufen muss. Also kann die Zeit niemals kleiner sein als die ausgerechneten 20 Sekunden, es sei denn, du willst die Funktion auch mittendrin abbrechen. Willst Du das?


    Die Zeiten sind in dem Programm fest definiert und nach dem Upload auf den Controller nicht mehr änderbar.

    Von daher kannst zu ja mit den Vielfachen der delay Zeiten arbeiten.


    Grundsätzlich kannst Du aber auch die Zeit festhalten, zu der die Aktion gestartet wird und zwischendurch immer abfragen, wieviel Zeit seitdem vergangen ist. Wird ein definierter Grenzwert erreicht, kann die Funktion mit "return" beendet werden. Es gibt aber, je nach Anforderung, viele Möglichkeiten das zu lösen.

    Schau Dir die anderen Videos an die ich Dir vorgeschlagen habe ("Das richtige Timing" und "Spielereien mit millies"). Da findest Du weitere Hinweise.

    Ein bisschen musst Du ja auch selber machen ;).


    Gruß Kai

  • Vielen lieben Dank, ist ja auch irgendwo logisch +/- eieiei


    Läuft wie gewünscht, was ich jetzt aber nicht finde ist wo ich im Sketch die Zeit extra definieren kann. Soweit ich es herauslese ist es auf 3 Wiederholungen ausgelegt und nicht auf Zeit. Denn, wenn ich jetzt die Geschwindigkeit oder die Haltezeit der einzelnen Positionen verändere verkürzt oder verlängert sich die Laufzeit.

  • Steck mal das rote Kabel vom Taster mit dem einen Ende in die (-) (blau markierte) Zeile. Der PIN 8 vom Uno ist laut Programm auf HIGH hat also +5V Spannung. Darum muss der Taster auf der Breadboardseite mit GND als (-) verbunden werden, weil der Taster den PIN ja auf LOW ziehen soll (Die technische Stromrichtung läuft nun einmal von (+) nach (-)).


    Das schwarze Kabel auf deinem Foto, hat gar keinen Kontakt mit dem Taster... Da ist die Trennzeile vom Breadboard dazwischen und somit kann ein Druck auf den Taster den Stromkreis nicht schließen. Dann pinne entweder das schwarze Kabel auf die andere Seite, in der auch der Schalter steckt oder positioniere den Schalter so auf der Trennzeile, dass er mit einer Hälfte da steckt, wo auch das schwarze Kabel ist.


    Du solltest Dir das erste Video, das ich vor ein paar Posts vorgeschlagen habe (Der einfache Einstieg in Arduino & Co. 5: Digitale Eingänge), wirklich mal in aller Ruhe anschauen. Dort ist das mit dem Schalter ausführlichst erklärt. Da ersparen Dir knappe 12 Minuten gucken viel Zeit, Rumprobieren und Fragen.


    Gruß Kai

  • Es liegt (zumindest auch) an deiner Verkabelung.


    Du hast den Taster am Servo angeschlossen. Das macht keinen Sinn. Der Servo muss so angeschlossen werden, als wäre kein Taster vorhanden. So wie Du es verkabelt hast, bekommt weder der Servo noch der Taster Strom.


    Du wirst also schon Masse und +5V auf das Breadbord legen müssen und dort Taster und Servo entsprechend stecken. Das Steuerkabel vom Servo kannst Du auf PIN9 stecken lassen, +5V und GND werden auf dem Breadboard gesteckt.


    Der Taster muss mit Masse(GND) und dem PIN8 verbunden werden.


    Der Stromkreis muss für Taster als auch für den Servo geschlossen sein.


    Mal so auf die Schnelle.


    Gruß Kai

  • Dankeschön, ich hab den Sketch jetzt geladen und es kommen keine Fehler somit denk ich mal das der passt.
    es passiert allerdings nix was aber eventuell an meiner Verkabelung liegen kann.

    Ich hab das so gemacht wie ich es in einigen Videos mit dem Taster gesehen habe.

    Ich häng mal ein Bild dazu denn zum erklären wäre mir das vermutlich zu schwer.

  • Ich habe da mal schnell was zusammengeklöppelt. Darum keine Garantie auf 100%ige Funktion. Kann sein dass ich noch etwas vergessen habe. Aber so in etwa denke ich, könnte Dein Problem gelöst werden.



    Gruß Kai

  • Also wie das mit Tastern funktioniert, hat René hier erklärt: Der einfache Einstieg in Arduino & Co. 5: Digitale Eingänge

    wie das mit der Zeit funktioniert hier: Der einfache Einstieg in Arduino & Co. 12: Das richtige Timing und hier Der einfache Einstieg in Arduino & Co. 13: Spielereien mit millis()


    Bei dem Beispiel ,das ich eingehend gebracht habe, reicht es den Taster einmal kurz zu drücken. Er muss nicht die ganze Zeit gedrückt gehalten werden.


    Ich habe dein Listing erst gesehen, nachdem ich diesen Post abgeschickt habe. Das muss ich mir erst mal anschauen.


    Gruß Kai

  • Ich kopiere mal eben rein wie der Sketch momentan aussieht. Wo und wie genau muss ich das jetzt dazwischen setzen ?



    #include <Arduino.h>

    #include <Servo.h>


    Servo servo; //Declaration for servo


    void setup()


    {

    servo.attach(9); //Declaration servo to Pin 8

    servo.write(0); //first Startposoition 0°

    }


    void loop() {


    delay(3000);//Start delay update value possible


    for (int i = 0; i < 90; i++) // run Pos 0° to Pos 90°

    {

    servo.write(i); //approach starting position

    delay(14); //servo speed update value possible

    }

    delay(3000); //delay time between each position change update value possible


    for (int i = 90; i < 180; i++) //run Pos 90° to Pos 180°

    {

    servo.write(i); //approach starting position

    delay(14); //servo speed update value possible

    }

    delay(3000); //delay time between each position change update value possible


    for (int i = 180; i > 90; i--) //run Pos 180° to Pos 90°

    {

    servo.write(i); //approach starting position

    delay(14); //servo speed update value possible

    }

    delay(3000); //delay time between each position change update value possible


    for (int i = 90; i > 0; i--) //run Pos 90° to Pos 0°

    {

    servo.write(i); //approach starting position

    delay(14); //servo speed update value possible

    }

    delay(3000); //delay time between each position change update value possible

    }

  • Vielen Dank, nur wie muss ich das ganze jetzt stecken ? Jetzt ist es so das wenn ich den Taster gedrückt halte der Servo sein Programm abspult.

    Den Taster muss ich ja auch erstmal angeben oder und wo und wie geb ich die Funktion ? Wie mach ich das ?

    Entschuldigung für die vielen Fragen.

  • Hmm so wie ich das verstehe brauchst du nur in in der Loop Schleife eine Taste abfragen, ob diese gedrückt wurde:


    Code
    1. void loop() {
    2. while (digitalRead(tasterPin)){}; // Diese Schleife läuft so lange, bis eine Taste gedrückt wurde.
    3. funktion_mache_60_sekunden_ingendwas(); // Nach dem Tastendruck läuft diese Aktion.
    4. // Loop beginnt von vorne und landet in der While-Schleife, die auf einen Tastendruck wartet.
    5. }

    Fertig.


    Gruß Kai

  • Hallo zusammen,

    Bin neu hier und hab gleich mehrere Fragen.


    ich möchte auf meiner Modellbahnanlage einige Tasteraktionen bauen.

    Ich habe zb einen Servo der sich bewegt 0/90/180/90/0 immer in Schleife. Ich kann die Dauer der Stopps so wie auch die Geschwindigkeit steuern ( dabei wurde mir aber schon zu 100% geholfen) . Soweit so gut, ich möchte allerdings das diese Aktion per Taster ausgelöst wird und für 60 Sekunden läuft und dann wieder endet.


    was mir also fehlt ist der Start per Taster und die Dauer der Aktion.
    ich hab mittlerweile schon soviel yt Videos gesehen und Artikel im www gelesen aber komme trotzdem nicht weiter.


    kann mir bitte jemand helfen ?