- Labornetzteil AliExpress         
Seite 2 von 7 ErsteErste 1234 ... LetzteLetzte
Ergebnis 11 bis 20 von 69

Thema: Welche Möglichkeiten der Fehlersuche hat man beim Arduino?

  1. #11
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    18.03.2013
    Beiträge
    242
    Anzeige

    Powerstation Test
    Danke für die ausführliche Info. Was ich UP nenne, nennst du offensichtlich Funktion. Soll mir recht sein.

    Zum Thema goto hier mal ein Beispiel. mir ist klar, dass man das auch anders machen kann, aber ist es hier nicht sinnvoll?

    Code:
      if (dir == 0 && (micros() - M5_microsalt)  > Schrittdauer)  {                            //  Drehrichtung
    
    
        switch (M5_i) {             //   es soll nur ein Schritt ausgeführt werden.
    
          case 0:
            M5_i = 1;
            goto M5_0;
            break;
          case 1:
            M5_i = 2;
            goto M5_1;
            break;
          case 2:
            M5_i = 3;
            goto M5_2;
            break;
          case 3:
            M5_i = 4;
            goto M5_3;
            break;
          case 4:
            M5_i = 5;
            goto M5_4;
            break;
          case 5:
            M5_i = 6;
            goto M5_5;
            break;
          case 6:
            M5_i = 7;
            goto M5_6;
            break;
          case 7:
            M5_i = 0;
            goto M5_7;
            break;
    
        }
    
      }   //  ************ ENDE if (dir == 0 && (micros() - M5_microsalt)  > Schrittdauer)
    
    
      else  if (dir == 1 && (micros() - M5_microsalt)  > Schrittdauer)  {      //  Drehrichtung
    
        switch (M5_i) {             //   es soll nur ein Schritt ausgeführt werden.
    
          case 0:
            M5_i = 1;
            goto M5_7;
            break;
          case 1:
            M5_i = 2;
            goto M5_6;
            break;
          case 2:
            M5_i = 3;
            goto M5_5;
            break;
          case 3:
            M5_i = 4;
            goto M5_4;
            break;
          case 4:
            M5_i = 5;
            goto M5_3;
            break;
          case 5:
            M5_i = 6;
            goto M5_2;
            break;
          case 6:
            M5_i = 7;
            goto M5_1;
            break;
          case 7:
            M5_i = 0;
            goto M5_0;
            break;
    
        }
    
    
    
    
    
    M5_0:
    
        digitalWrite(p1, HIGH);
        digitalWrite(p2, LOW);
        digitalWrite(p3, LOW);
        digitalWrite(p4, LOW);
        goto M5_Schritt;
    
    M5_1:
    
        digitalWrite(p1, HIGH);
        digitalWrite(p2, HIGH);
        digitalWrite(p3, LOW);
        digitalWrite(p4, LOW);
        goto M5_Schritt;
    
    M5_2:
    
        digitalWrite(p1, LOW);
        digitalWrite(p2, HIGH);
        digitalWrite(p3, LOW);
        digitalWrite(p4, LOW);
        goto M5_Schritt;
    
    M5_3:
    
        digitalWrite(p1, LOW);
        digitalWrite(p2, HIGH);
        digitalWrite(p3, HIGH);
        digitalWrite(p4, LOW);
        goto M5_Schritt;
    
    M5_4:
    
        digitalWrite(p1, LOW);
        digitalWrite(p2, LOW);
        digitalWrite(p3, HIGH);
        digitalWrite(p4, LOW);
        goto M5_Schritt;
    
    M5_5:
    
        digitalWrite(p1, LOW);
        digitalWrite(p2, LOW);
        digitalWrite(p3, HIGH);
        digitalWrite(p4, HIGH);
        goto M5_Schritt;
    
    M5_6:
    
        digitalWrite(p1, LOW);
        digitalWrite(p2, LOW);
        digitalWrite(p3, LOW);
        digitalWrite(p4, HIGH);
        goto M5_Schritt;
    
    M5_7:
    
        digitalWrite(p1, HIGH);
        digitalWrite(p2, LOW);
        digitalWrite(p3, LOW);
        digitalWrite(p4, HIGH);
        goto M5_Schritt;

  2. #12
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    Das ganze wiederholt sich viel zu oft unnötigerweise.

    Statt viele Male
    Code:
        digitalWrite(p1, wert);
        digitalWrite(p2, wert);
        digitalWrite(p3, wert);
        digitalWrite(p4, wert);
    würde einmal
    Code:
    void SetBits(int v1, int v2, int v3, int v4)
    {
        digitalWrite(p1, v1);
        digitalWrite(p2, v2);
        digitalWrite(p3, v3);
        digitalWrite(p4, v4);
    }
    reichen was man dann z.B. als SetBits(LOW, HIGH, HIGH, LOW); aufruft. Dann hat das Programm schon viele Zeilen verloren.

    So müsste man mehrmals da drüber gehen. Am Ende hätte das Programm vielleicht noch 10 % der jetzigen Länge. Dann hätte man schon viel für die Fehlersuche gewonnen.

    - - - Aktualisiert - - -

    Als Ergänzung, selbst wenn im obigen Falle p1 bis p4 Variablen sind, könnte man sowas machen

    Code:
    struct MotorPin
    {
      int p1;
      int p2;
      int p3;
      int p4;
    };
    
    const MotorPin pins[] = { {1, 2, 3, 4}, {5, 6, 7, 8} , /* mehr Pins */}; // nur Beispielwerte
    
    void SetBits(int motor, int v1, int v2, int v3, int v4)  // Motornummer beginnt hier bei 0
    {
        digitalWrite(pins[motor].p1, v1);
        digitalWrite(pins[motor].p2, v2);
        digitalWrite(pins[motor].p3, v3);
        digitalWrite(pins[motor].p4, v4);
    }
    Geändert von Mxt (14.09.2016 um 18:41 Uhr)

  3. #13
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    18.03.2013
    Beiträge
    242
    Hallo,

    während der Fehlersuche frage ich mich, wie ein Serial.Print-Befehl im Programm verarbeitet wird.
    Bleibt das Programm an dieser Stelle stehen, bis z.B. eine Quittung über den erfolgreichen Sendevorgang vorliegt oder wird der Befehl nur initiiert und das Programm setzt die Abarbeitung der folgenden Befehle unverzüglich fort.

    Wie ist das bei 4 -5 Serial.print's direkt hintereinander? Kann zwischen den einzelnen Serial.print's noch eine Programmabarbeitung erfolgen, so dass die auf dem Monitor angezeigten Werte nicht exakt den selben Programmzustand zeigen?
    Nur zur Info: ich habe " Serial.begin (250.000);" eingestellt.

    vG

    fredyxx

  4. #14
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    66
    Beiträge
    2.435
    Hallo fredyxx,
    Zitat Zitat von fredyxx Beitrag anzeigen
    während der Fehlersuche frage ich mich, wie ein Serial.Print-Befehl im Programm verarbeitet wird.
    Bleibt das Programm an dieser Stelle stehen, bis z.B. eine Quittung über den erfolgreichen Sendevorgang vorliegt oder wird der Befehl nur initiiert und das Programm setzt die Abarbeitung der folgenden Befehle unverzüglich fort.
    Grundsätzlich benötigt die Ausgabe von Debug-Informationen etwas Zeit.
    Mit und ohne ist das Timing auf alle Fälle unterschiedlich!

    Zu deinem Grundproblem:
    Bevor noch irgendeine Zeile C ausgeführt wird, werden die globalen Variablen initialisiert. Die meisten bekommen den Wert 0
    int i;
    Bei
    int j = 3;
    Wird der entsprechende Wert (hier 3) zugewiesen.
    Dies wird aber nur nach einem Reset durchgeführt.
    Andernfalls haben dein globalen Variablen den letzten vom Programm zugewiesenen Wert.


    Wenn ich dein Programm noch richtig im Kopf habe hast du Hilfsvariablen in der Form
    Motor_fertig = TRUE;
    Womit du weiterschaltest.
    Bei einem zweiten Aufruf bleiben diese auf TRUE, wenn du sie nicht extra zurück setzt.
    Dann rasselt halt alles durch.

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

  5. #15
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    Hallo,

    Zitat Zitat von fredyxx Beitrag anzeigen
    Bleibt das Programm an dieser Stelle stehen, bis z.B. eine Quittung über den erfolgreichen Sendevorgang vorliegt oder wird der Befehl nur initiiert und das Programm setzt die Abarbeitung der folgenden Befehle unverzüglich fort.
    Ganz allgemein erfolgt bei Arduiono kein Test auf erfolgreichen Sendevorgang. Wenn keiner empfängt sind die Daten halt weg.

    Ob das print wartet, hängt vom Arduino Modell ab:
    Bei den meisten Modellen gehen die Daten über UART vom Hauptcontroller zum USB-Controller auf dem Board. Das ist entweder ein zweiter Controller (meist ein 16U2) oder nur ein seriell zu USB Wandler (FTDI, CH340, ...). Das Print muss in diesem Falle warten, bis die Daten aus dem UART raus sind.

    Dieser Vorgang kann durch einen Interrupt unterbrochen werden, z.B. wenn ein Library verwendet wird, die damit arbeitet. Was hinter dem print steht, kommt aber erst dran, wenn das print fertig ist.

    Bei Arduinos mit Controllern, die selbst einen USB-Anschluss haben (Leonardo, Micro, Due, Teensy, ...), ist ein print meist nur ein sehr schneller Kopiervorgang, um den Rest kümmert sich die USB-Hardware im Chip.

  6. #16
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    18.03.2013
    Beiträge
    242
    Zitat Zitat von Peter(TOO) Beitrag anzeigen
    Hallo fredyxx,

    Grundsätzlich benötigt die Ausgabe von Debug-Informationen etwas Zeit.
    Mit und ohne ist das Timing auf alle Fälle unterschiedlich!


    MfG Peter(TOO)
    ok, aber kann man sicher sein, dass aufeinder folgende Serial.Print's auch direkt nacheinander gesendet werden und das Programm auch dann erst weiter geht?

    Wenn ich dein Programm noch richtig im Kopf habe hast du Hilfsvariablen in der Form
    Motor_fertig = TRUE;
    Womit du weiterschaltest.
    Alle Achtung! Das hast du noch genau richtig im Kopf. Deshalb setze ich in der LOOP mit dem STOP-Schalter auch alle Mx-fertig's auf false und erst wenn ich den wieder umschalte, kann das Justierprogramm wieder beginnen. Bei M1 ist das auch so, aber direkt danach sind alle Mx-fertig's auf true!!!???????????????????

    vG
    fredyx

  7. #17
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    66
    Beiträge
    2.435
    Hallo fredyx,
    Zitat Zitat von fredyxx Beitrag anzeigen
    ok, aber kann man sicher sein, dass aufeinder folgende Serial.Print's auch direkt nacheinander gesendet werden und das Programm auch dann erst weiter geht?
    Im einfachsten Fall wartet man bis das Senderegister leer ist und schreibt dann das nächste Zeichen in das Sende-Register. So lange man wartet, ist die CPU blockiert, bzw. kann nur Interrupts bearbeiten. Das geht dann ganz ohne Interrupts, ist aber die langsamste Variante. Zudem hängen die Zeiten direkt von der Baudrate ab.

    Bei der eleganteren Art richtet man einen Puffer ein und der Print-Befehl kopiert die Zeichen in diesen Puffer. Nach dem Kopieren kann die CPU weiter das Programm abarbeiten. Wenn das Sende-Register leer ist erzeugt es einen Interrupt und die ISR kopiert dann das nächste Zeichen aus dem Puffer ins Sende-Register.
    Es braucht dann noch etwas Aufwand für die Pufferverwaltung. Wenn man das erste Zeichen in den leeren Puffer schreibt muss man den Interrupt anwerfen. Umgekehrt muss die ISR den Interrupt abschalten, wenn das letzte Zeichen aus dem Puffer gelesen wird.
    Wenn der Puffer voll ist, muss man warten, bis ein Zeichen gesendet wurde, dann ist man gleich langsam wie bei der einfachen Variante.
    Noch etwas schneller wird es, wenn man die Daten, sofern vorhanden, per DMA vom Puffer in das Sende-Register kopiert. Die Verwaltung wird dafür etwas aufwändiger, dafür wird die ISR seltener aufgerufen (Nur wenn die DMA fertig ist und somit nicht für jedes Zeichen).

    Die Technik mit dem Puffer funktioniert auch beim Empfangen und hat den Vorteil, dass man keine Zeichen verliert, besonders wenn man noch Handshake (XON XOFF) implementiert.

    Leider stehen viele Programmierer mit den Interrupts etwas auf Kriegsfuss und die erste Variante ist deshalb sehr häufig anzutreffen. Allerdings entwickelt man den Treiber eigentlich nur einmal im Leben für eine Programmiersprache. Die Anpassung an unterschiedliche µCs betrifft dann eigentlich nur die Handhabung des Interrupt-Controllers und des Sende-Registers, der Rest ändert sich eigentlich nicht.

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

  8. #18
    HaWe
    Gast
    switch/case ist nichts anderes als ein goto.
    Die case (irgendwas) sind nichts anderes als Sprungmarken für gotos, daher müssen es in C immer auch Integer-Konstanten sein (und keine Floats oder logische Ausdrücke).
    So ungern hier also manche das goto in C-Programmen sehen: es ist nur persönliches Ästhetikempfinden, nicht mehr und nicht weniger

    an fredyxx:
    wenn du sicher bist, dass deine Sprünge im richtigen Moment an die richtige Stelle führen, ist das kein Grund, sie durch switch/case Anweisungen zu ersetzen.
    Allerdings müssen sie beide in jedem Falle immer im richtigen Moment an die richtige Stelle führen.
    Bist du also sicher, dass sie stimmen, lass sie drinnen - und such den Fehler woanders.
    Goto Anweisungen innerhalb von switch/case ist allerdings reichlich doppelt gemoppelt und wirklich extrem unschöner Programmierstil.

    zum Debuggen mit serial:
    Du kannst Wartepunkte einfügen, indem du in dein Programm ein Warten auf einen Buttondruck und wieder loslassen einfügst:
    Code:
    #define testpin 13 // or whatever
    Code:
    while(!testpin);
    Serial.print(irgendwas);
    while(testpin);
    Geändert von HaWe (16.09.2016 um 14:03 Uhr)

  9. #19
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    18.03.2013
    Beiträge
    242
    Hallo HaWe,

    deine Antwort hat mir in zweierlei Hinsicht mal richtig gut getan. DANKE dafür!

    1. Dieser Satz:

    es ist nur persönliches Ästhetikempfinden, nicht mehr und nicht weniger
    Ich bin auch noch als Arduinoanfänger nach einem halben Jahr Aufwand an dem Hobby-Projekt ziemlich weit davon entfernt das Programm um zu schreiben, denn da würden sicher auch wieder neue Probleme auftreten. Man ist ja häufig auch schon froh, wenn man nicht eine optimale sondern überhaupt eine Lösung findet. Trotzdem werde ich in Zukunft mehr darüber nachdenken, ob ich mehr Case und Funtionen verwenden werde.
    Außerdem habe ich zZ eine Spur, wo der Fehler liegen könnte, nämlich im Umgang mit dem Signal des STOP-Tasters, dessen zeitlicher Signalablauf ich wohl nicht vollständig durchschaut und daher auch nicht richtig verarbeitet habe. Bin mir aber noch nicht sicher.
    Maßnahme gegen Tasterprelllen hatte ich schon vorgesehen.

    Außerdem hat mir bei der Fehlersuche Folgendes geholfen:
    ich habe an den Stellen, von denen ich sicher wissen wollte, ob das Programm da durchläuft oder nicht, einen Ausgang mit LED gesetzt, der im Programm mit Sicherheit nicht zurückgesetzt wird. Dadurch brauchte ich mir keine Gedanken über die zeitliche Verarbeitung von Serial.print zu machen und ich habe sofort erkannt, bei welchem Prozesschritt das passiert.

    2.
    So was wie dein Vorschlag zu "zum Debuggen mit serial" war das, was ich auf meine ursprüngliche Frage als Antwort erhofft hatte.

    Ich werde nicht aufgeben und bei Erfolg berichten.

    vG

    fredyxx

  10. #20
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.652
    switch/case ist nichts anderes als ein goto .. Die case (irgendwas) sind nichts anderes als Sprungmarken für gotos ..
    Wirklich? Ohh! Das ist für mich jetzt total neu.

    Ich dachte immer die Anweisung "case expr :" in der switch-Schleife wird abgearbeitet, solange kein break folgt bzw. die switch-Schleife durch eine andere Anweisung verlassen wird wie z.B. return. Deshalb fürchtete ich, dass ohne break oder return eine Anweisung wie das goto beim nächsten return wieder in der switch-Schleife landet. Mit kaum kontrollierbarem weiteren Ablauf. Abgesehen davon, dass meines Wissens nach, das Sprungziel nur innerhalb des Gültigkeitsbereiches der Marke liegen, d.h. nur in der jeweiligen Funktion liegen darf.

    Frage: Bedeutet die oben zitierte Aussage, dass durch das "goto label;" innerhalb eines "case expr :" KEIN Rücksprung in die switch-Schleife erfolgt? Nie und Nimmer?
    Frage: Wie kriegt der Stack diesen Ablauf gebacken ?
    Ciao sagt der JoeamBerg

Seite 2 von 7 ErsteErste 1234 ... LetzteLetzte

Ähnliche Themen

  1. 18 PWM Kanäle - Welche Möglichkeiten?
    Von Hardware-Entwickler im Forum Elektronik
    Antworten: 7
    Letzter Beitrag: 19.12.2015, 14:16
  2. Antworten: 8
    Letzter Beitrag: 21.10.2014, 09:18
  3. Möglichkeiten der AVR/Arduino PWM?
    Von ichbinsisyphos im Forum Arduino -Plattform
    Antworten: 10
    Letzter Beitrag: 23.02.2013, 09:03
  4. Spannungen mit PC-Computer Messen. Welche Möglichkeiten?
    Von petermetertr im Forum PC-, Pocket PC, Tablet PC, Smartphone oder Notebook
    Antworten: 14
    Letzter Beitrag: 26.08.2009, 16:36
  5. 20 mikrovolt-Hirnwellen registrieren-Welche möglichkeiten?
    Von Thomas Wellheim im Forum Allgemeines zum Thema Roboter / Modellbau
    Antworten: 13
    Letzter Beitrag: 18.12.2004, 18:43

Berechtigungen

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

fchao-Sinus-Wechselrichter AliExpress