-         

Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 30

Thema: Programm ablauf langsam

  1. #1
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    18.03.2013
    Beiträge
    235

    Programm ablauf langsam

    Anzeige

    Hallo,

    ich habe ein Baggermodell mit Arduino MEGA und 6 Schrittmotoren. Fast alles klappt zZ prima mit einer Ausnahme.
    Für die Schrittmotoransteuerung habe ich ein selbsterstelltes Unterprogramm geschrieben, dessen Aufruf für einen Motor z.B. so aussieht:

    M1_drive(41, 43, 45, 47, n, 30, 0); // 41, 43, 45, 47 sind die Ausgänge, n = Anzahl der Umdrehungen,
    // 30 = Anzahl der Umdrehungen/min; 0 = Drehrichtung

    Mit den Geschwindigkeiten, die die Zahnstangenantriebe fahren, bin ich für den normalen Ablauf zufrieden. Es gibt jedoch eine Unterprogramm "Justierung" mit dem ich nach einander alle Antriebe in eine definierte Ausgangsstellung fahren kann. Bei dieser Betriebsart schleichen die Antriebe jedoch nur, auch wenn ich den Parameter für die U/min in den entsprechenden Aufrufen vergrößere. Die Unterprogramme Mx_drive benutze ich in jedem Fall, jedoch für jeden Motor ein separates.
    Zunächst hatte ich die Library Bounce2 in Verdacht, mit der ich das Prellen eines Tasters, der mit Erreichen der Grundstellung eines Antriebs betätigt wird, unterdrücken will. Die Einstellung von 1 ms reichte dafür aus. Aber auch wenn ich 100 ms einstellte, liefen die Antriebe nicht langsamer, so dass ich meine, dass diese Library den normalen Programmzyklus nicht verzögert. Oder liege ich da falsch?

    Evtl. fällt jemandem spontan auf, was die Ursache für diese unterschiedlichen Geschwindigkeiten sein könnte.

    Ich habe den Teil des Codes für Motor1 aus dem Unterprogramm Justierung angefügt und ein Bild des entsprechenden Flussdiagramms.

    Code:
    //  **************************************   UP Justierung   **************************************
    
    void Justierung() {
      static boolean M1_fertig = false;
      static boolean M2_fertig = false;
      static boolean M3_fertig = false;
      static boolean M4_fertig = false;
      static boolean M5_fertig = false;
      static boolean M6_fertig = false;
      static boolean M1_laeuft = false;
      static boolean M2_laeuft = false;
      static boolean M3_laeuft = false;
      static boolean M4_laeuft = false;
      static boolean M5_laeuft = false;
      static boolean M6_laeuft = false;
      static boolean Z_EIN;               //  true, solange Timer 1 läuft
    
    
      if (M1_fertig == true)  {
    
    
        goto M2_Sprung;    // M1 wird übersprungen
      }
    
      if (JustPin == HIGH)    {
        M1_laeuft = true;
    
        M1_drive(41, 43, 45, 47, 30, 3, 1);   //   41, 43, 45, 47, Mx_n, Mx_v, Mx_dir  ;  für den MEGA
     
    
        return;
    
      }    //  *********** ENDE  if (JustPin == HIGH)
    
    
      if (Zeit_EIN(M1_laeuft) == true)   {    //  Aufruf des UPs Zeit_EIN(), das die Zeit startet, in der JustPin LOW sein muss, damit eine Motor übersprungen wird.
    
        return;   // Sprung aus UP Justierung
      }
    
    
    
       timer1.disable(zeitId);         // Timer1 löschen
    
      M1_fertig = true;        // wenn Auftrag vom Hauptprogramm erledigt ist
      M1_Start ==  true;
      Zeitueberlauf = false;    // eigenes Zeitsignal löschen
      TimerAktiv  = false;
      lzahn1_alt = 1.0;
    
      digitalWrite(41, LOW);   // alle LOW, damit der Motor im Stillstand stromlos ist.
      digitalWrite(43, LOW);
      digitalWrite(45, LOW);
      digitalWrite(47, LOW);
    
    
    
    
    M2_Sprung:      // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>          ab hier Start Motor 2
    Klicke auf die Grafik für eine größere Ansicht

Name:	Scannen0001.jpg
Hits:	8
Größe:	74,6 KB
ID:	31958

    Mir ist klar, dass das mit diesen Informationen keine einfache Frage ist.

    Welche Möglichkeiten kennt ihr, den Verursacher zu finden?

    Noch zur Erklärung:
    Zahnstangengeschwindigkeit von 13 mm/s ist ok
    Bei Justierung nur ca. 2 mm/s

    vG

    fredyxx
    Geändert von fredyxx (28.08.2016 um 11:53 Uhr)

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von i_make_it
    Registriert seit
    29.07.2008
    Ort
    Raum DA
    Alter
    49
    Beiträge
    2.433
    Ich sehe Spagetticode (GOTOaus einem UP das mit RETURN Verlassen werden soll)

    Code:
    void Justierung() {
    
        if (M1_fertig == true)  {
          goto M2_Sprung;    // M1 wird übersprungen
        }
    
        if (JustPin == HIGH)    {
          return;
        }    //  *********** ENDE  if (JustPin == HIGH)
    
        return;   // Sprung aus UP Justierung
     }
    
    M2_Sprung:
    Was sagt denn Dein Stack und dein Heap zu dem Konstrukt? läuft da nicht was auf Dauer über oder hast Du es noch nicht lang genug laufen lasse?
    Du rufst ja Justierung() auf und jedesmal wenn Du mit einem GOTO rausspringst verlässt DU es nicht mehr (zumindest nicht für den Prozessor).
    Wenn schon GOTO dann definitiv nur innerhalb der Funktion. Verlassen solltest Du die Funktion aber mit einer korrekten Abbruchbedingung und einem Rückgabewert, der in der Hauptschleife verarbeitet wird und zum Aufruf von dem was nach M2_Sprung kommt, führt.

    Um zu verstehen wann man GOTO einsetzen kann und wann es gfährlich ist, müsste jeder eigentlich erst mal Assembler lernen. Da gibt es nämlich nur GOTO (Jump / Farjump) Allerdings muß man sich da auch selbst darum kümmern Register zu retten, Stackpointer und den Heap zu verwalten.
    Hochsprachen nehmen einem das ales ab, haben aber oft noch das GOTO (JUMP) drin.
    Ohne das verständniss davon was im Hintergrund läuft, kann GOTO an der falschen Stelle und falsch eingesetzt zu einem (für das Programm) tödlichen Bumerang werden.
    Nicht umsonst ist die Fraktion entstanden die GOTO generell verteufelt.
    Als Anfänger sollte man GOTO meiden bis man verstanden hat was wann wo geschieht und man in der Lage ist zu erkennen wo ein GOTO schlanken Code erzeugt und wo es Chaos und Abstürze verursacht.
    Geändert von i_make_it (28.08.2016 um 12:33 Uhr)

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    59
    Beiträge
    2.435
    Hallo,

    Kann es sein, dass dein Unterprogramm dauernd aufgerufen wird und somit der Motor dauernd gestartet wird?
    M1_laeuft wird zwar gesetzt, aber wo wird es abgefragt, bzw. was bewirkt es?

    M1_drive() sollte nicht aufgerufen werden, wenn M1_lauft gesetzt ist.

    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  4. #4
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    18.03.2013
    Beiträge
    235
    Die Sprungfunktion täuscht hier, weil in dem Unterprogramm Justierung noch 5 mal so ein Programmteil für die anderen Motoren existiert (den Teil wollte ich euch ersparen) und ich springe dann nur innerhalb des UP's zum nächsten Motor, wenn der vorhergehende seine Position erreicht hat.
    Was sind Stack und Heap?
    Das Programm arbeitet ja auch sonst schnell und ordnungsgemäß, wenn ich mit der Schaufel über 2 Gelenke des Baggerarms eine konkrete xy-Position anfahre.

    vG

    fredyxx

    - - - Aktualisiert - - -

    Zitat Zitat von Peter(TOO) Beitrag anzeigen
    Hallo,

    Kann es sein, dass dein Unterprogramm dauernd aufgerufen wird und somit der Motor dauernd gestartet wird?
    M1_laeuft wird zwar gesetzt, aber wo wird es abgefragt, bzw. was bewirkt es?

    M1_drive() sollte nicht aufgerufen werden, wenn M1_lauft gesetzt ist.

    MfG Peter(TOO)
    Das ist nötig, weil in diesem UP festgestellt wird, ob die 4 Ausgänge für den Stepper verändert werden müssen(nächster Schritt) . Wenn die Schrittdauer noch nicht erreicht ist, wird das UP sofort wieder verlassen.

    Diese Lösung habe ich nach der Diskussion in diesem Thread für mich gewählt und bin bis auf das Justieren auch damit zufrieden.

    http://www.roboternetz.de/community/...hlight=fredyxx



    vG

    fredyxx

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    599
    Zitat Zitat von i_make_it Beitrag anzeigen
    Du rufst ja Justierung() auf und jedesmal wenn Du mit einem GOTO rausspringst verlässt DU es nicht mehr (zumindest nicht für den Prozessor).
    Das kann es eigentlich nicht sein. Arduino ist C++ und das erlaubt nur Sprünge innerhalb einer Funktion. Trotzdem ist die Verwendung von goto zu dem hier verwendeten Zweck ganz allgemein schlechter Stil.

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    2.426
    ich finde den ganzen Hinweis/Post mit dem Sprung aus der Funktion heraus für gar nicht nachvollziehbar:
    Sprung und Sprungadresse liegen doch innerhalb ein und derselben Funktion, oder etwa nicht?
    Ansonsten müsste auch der Arduino-Compiler meckern, was er aber offenbar doch nicht tut. Dann aber hätte es nur zur Folge, dass der Sprung komplett rausoptimiert wird, denn Sprünge aus einer Funktion heraus gehen ja gar nicht, wie mxt richtig angemerkt hat.
    Muss also andere Gründe haben...


    goto allerdings finde ich persönlich für weder schlechten noch guten Stil, es vereinfacht oft komplizierte Abbruchbedingungen und ist daher ebenso legitim wie if, for, while, case (was ja auch wieder nur ein Sprung ist). Wer goto benutzen will, soll es tun, manchmal macht es Dinge sogar übersichtlicher.
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

  7. #7
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    59
    Beiträge
    2.435
    Hallo fredyxx,
    Zitat Zitat von fredyxx Beitrag anzeigen
    Das ist nötig, weil in diesem UP festgestellt wird, ob die 4 Ausgänge für den Stepper verändert werden müssen(nächster Schritt) . Wenn die Schrittdauer noch nicht erreicht ist, wird das UP sofort wieder verlassen.

    Diese Lösung habe ich nach der Diskussion in diesem Thread für mich gewählt und bin bis auf das Justieren auch damit zufrieden.
    Tja, woher weiss man dies, wenn man den Code nicht kennt?

    Und wie funktioniert Zeit_EIN()?
    Kehrt die Funktion sofort zurück oder erst wenn die Zeit abgelaufen ist?

    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  8. #8
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    18.03.2013
    Beiträge
    235
    Zitat Zitat von Mxt Beitrag anzeigen
    Das kann es eigentlich nicht sein. Arduino ist C++ und das erlaubt nur Sprünge innerhalb einer Funktion.
    Wenn Funktion = Unterprogramm ist, dann mache ich das auch nicht anders.

    Zitat Zitat von Mxt Beitrag anzeigen
    Trotzdem ist die Verwendung von goto zu dem hier verwendeten Zweck ganz allgemein schlechter Stil.
    Ich denke mit diesen unvollständigen Informationen zu dem Gesamtprogramm ist das nicht zu beurteilen.

    - - - Aktualisiert - - -

    Zitat Zitat von Peter(TOO) Beitrag anzeigen
    Hallo fredyxx,

    Tja, woher weiss man dies, wenn man den Code nicht kennt?

    MfG Peter(TOO)
    Ja, sehe ich ein. Aber den vollständigen Code von über 2000 Zeilen möchte ich keinem zumuten.

    Zitat Zitat von Peter(TOO) Beitrag anzeigen
    Hallo fredyxx,
    Und wie funktioniert Zeit_EIN()?
    Kehrt die Funktion sofort zurück oder erst wenn die Zeit abgelaufen ist?
    MfG Peter(TOO)
    Kommt mit Sicherheit sofort zurück, weil ich den jeweiligen Motor mit einem Taster vor Ablauf der Zeit stoppen kann. Also muss der Zyklus in der Zeit weiter laufen.

    vG

    fredyxx

  9. #9
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    599
    Zitat Zitat von fredyxx Beitrag anzeigen
    Ich denke mit diesen unvollständigen Informationen zu dem Gesamtprogramm ist das nicht zu beurteilen.
    C++ Erfinder Stroustrup schreibt dazu (in "The C++ Programming Language", Kap. 9.6)
    The goto has few uses in general high level programming, but it can be very useful when C++ code is generated by a program rather than written directly by a person; for example, gotos can be used in a parser generated from a gramar by a parser generator.

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.10.2014
    Beiträge
    2.426
    also wenn Code langsam läuft, und es an dem geposteten Snippet nicht liegt (was noch zu beweisen wäre), dann muss es zwangsweise irgendwo am/im restlichen Programm liegen,
    - doch dazu muss es man kennen, und mag es noch so groß oder klein sein
    ·±≠≡≈³αγελΔΣΩ∞ Schachroboter:www.youtube.com/watch?v=Cv-yzuebC7E Rasenmäher-Robot:www.youtube.com/watch?v=z7mqnaU_9A8

Seite 1 von 3 123 LetzteLetzte

Ähnliche Themen

  1. UART, zeitlicher Ablauf Subprogramme
    Von mollyman im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 6
    Letzter Beitrag: 14.06.2013, 18:10
  2. Programm-Ablauf wird nicht eingehalten.
    Von RobbyMartin im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 5
    Letzter Beitrag: 11.06.2011, 16:39
  3. Programm zu langsam?
    Von Hübi im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 16
    Letzter Beitrag: 05.03.2009, 18:03
  4. Ablauf von Programmen generell
    Von The Man im Forum Assembler-Programmierung
    Antworten: 2
    Letzter Beitrag: 18.08.2007, 15:21
  5. Ablauf der IRSs mit SIGNAL
    Von weijr im Forum Elektronik
    Antworten: 5
    Letzter Beitrag: 03.12.2006, 22:47

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •