- 3D-Druck Einstieg und Tipps         
Seite 3 von 3 ErsteErste 123
Ergebnis 21 bis 28 von 28

Thema: Teensy 3.2 +++ Interrupt, Übergabeparameter

  1. #21
    HaWe
    Gast
    Anzeige

    E-Bike
    ich habe für single-thread Programme bisher keine loops, die länger als 20ms gedauert haben (was schon sehr viel ist für schnelle MCUs wie esp8266/32, Arduino Due, SAMD51), und wenn einzelne Funktionen in Einzelfällen in speziellen Programmen viel Zeit brauchen, verwende ich den ESP32 oder den Due mit multithreading, die sind mit dem Teensy vergleichbar - dann lauft die btn lib in einem eigenen thread sehr schnell durch und die zeitintensive Funktion tut es auch ungestört in einem eigenen Thread.
    Alles also kein Problem, aber @Klebwax: du kannst sicher gerne deinen eigenen kompilierbaren Code hier posten, er muss nur eben auch für den Teensy funktionieren (edit: und ntl passend für Arduino IDE und API, die für den Teensy verwendet werden).
    Für den Teensy andererseits gibt es eine eigene MT lib (falls die Teensy-Entprell-Lib nicht ausreicht): TeensyThread, doch ob das für den OP wirklch ein Zeit-Problem ist, wird er selber erstmal testen und dann mitteilen müssen.
    Das einfachste wäre IMO aber als erster Schritt eine einfache Statemachine, die einfach mindestens 30ms wartet.
    Geändert von HaWe (24.11.2019 um 09:31 Uhr)

  2. #22
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    Zitat Zitat von HaWe Beitrag anzeigen
    Für den Teensy andererseits gibt es eine eigene MT lib (falls die Teensy-Entprell-Lib nicht ausreicht): TeensyThread, doch ob das für den OP wirklch ein Zeit-Problem ist, wird er selber erstmal testen und dann mitteilen müssen.
    Das einfachste wäre IMO aber als erster Schritt eine einfache Statemachine, die einfach mindestens 30ms wartet.
    Ja, das sehe ich auch so.

    Wichtig ist es noch zu wissen: Auf einem ARM haben Interrupts Prioritäten und können sich teilweise gegenseitig unterbrechen. Nur so ist es auch möglich, die vielen Hardwarekomponenten des Chips quasi parallel zu benutzen. Ein Interrupt sollte also nur wie ein kurzes Augenzwinkern sein, nur die allernötigsten Dinge tun. Niemals aktiv warten und erst recht nicht während des Wartens alle anderen Interrupts sperren. Damit legt man nur Sachen lahm, die man wahrscheinlich als nächstes gebraucht hätte.

    Im Prinzip ist es schon richtig, dass die Zeit in der Loop nur das ist "was übrig bleibt". Aber, wie HaWe schon sagte, ist das bei einem schnellen Controller sehr viel. Außerdem ist die Arbeit mit der loop nun mal der "Arduino Way" und die Programme bleiben portabel zu anderen Typen. Außerdem bekommt man bei loop Programmen besser ein Gefühl für die vorhandene Rechenleistung. Wenn man alles in Timer Interrupts packt, sieht man das nicht so gut.

    Wenn man später feststellt, dass manche Dinge in der Loop nicht so gut aufgehoben sind, kan man im nächsten Schritt zu einem Timer oder ggf. DMA greifen.

  3. #23
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    07.03.2011
    Beiträge
    1.899
    Zitat Zitat von Mxt Beitrag anzeigen
    Im Prinzip ist es schon richtig, dass die Zeit in der Loop nur das ist "was übrig bleibt". Aber, wie HaWe schon sagte, ist das bei einem schnellen Controller sehr viel.
    Nun, alle Embeded-Programme haben die "Mainloop". Wenn man aber das Timing fürs Tastenentprellen oder die Mikroschritte in die Mainloop zieht, sind brauchbare Systeme kaum möglich. Ich versuche mir gerade vorzustellen, wie ich einen G-Code Interpreter aufbaue, der immer kürzer als ein Mikroschritt des Steppers läuft. Ansonsten würde der Motor schon bei der Ansteuerung Schritte verlieren. Man kann natürlich immer einen schnelleren Prozessor nehmen muß sich aber fragen, warum es andere mit einem langsameren auch schaffen.

    Die Arm sind schon mächtig, in einem Hoverboard steuert einer das Timing von 2 BLDC und das Balancieren, aber sicher nicht mit einem Arduino Framework.

    Außerdem ist die Arbeit mit der loop nun mal der "Arduino Way" und die Programme bleiben portabel zu anderen Typen. Außerdem bekommt man bei loop Programmen besser ein Gefühl für die vorhandene Rechenleistung. Wenn man alles in Timer Interrupts packt, sieht man das nicht so gut.
    Richtig, ein System, programmieren zu lernen und die Komplexität von Interrupten und Dingen wie DMA vor dem Anwender zu kapseln. Zum Üben, wie man etwas macht ohne die CPU mit delays zu blockieren mag das angehen.

    Ich versuche meine Systeme so aufzubauen, daß die Mainloop möglichst leer ist. Eigentlich will ich da nur ein sleep() sehen. Der ganze Rest läuft in Interrupt Handlern. Nested Interrupts können einem dabei helfen, es geht häufig aber auch so. Bei alten 386 SBCs konnte man das direkt fühlen. Wenn der im DOS-Prompt stand, wurde die CPU richtig heiß, stand er im Linux-Prompt blieb sie kalt. Da war wohl ein sleep() in der Mainloop.

    MfG Klebwax
    Strom fließt auch durch krumme Drähte !

  4. #24
    HaWe
    Gast
    Klebwax,
    du bist hier im Arduino Forum, da arbeitet man mit der Arduino IDE und Arduino APIs, aber nichtsdestotrotz mit völlig legalem C++, das man sogar auf Raspberry Pis zum Laufen bekommt. Und dabei sogar zusätzlich MT mit pthread, std::thread oder teensyThread zur Verügung stellt.
    Wenn du also hier Lösungen vorschlägst, dann ist es wschl für den OP wenig zweckdienlich, soweit du hier die gesamte Teensy-Arduino-Programmierbasis schlechtredest und dann noch nicht einmal einen konstruktiven compilierbaren Gegenvorschlag als Alternative für das Problem des OPs anbietest:
    Das ist eine ziemlich billige Miesmachertour, wie schon öfters.

  5. #25
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    07.06.2019
    Beiträge
    147
    Ich DANEK euch Allen für eure tollen Beiträge, Gedanken und Vorschläge.

    Zitat Zitat von HaWe Beitrag anzeigen
    Klebwax,
    Das ist eine ziemlich billige Miesmachertour, wie schon öfters.
    Ich denke, dass er nur die Grenzen des Arduino/Teensy-Machbaren aufzeigen wollte. Das ist völlig ok und hat mir nur kurz verwirrt
    Was ich bei allen Beiträgen heraus lese ist aber, dass eis keine "kleine", "schnelle" und "universelle" Lösung gibt.

    Mit der "Teensy-Entprell-Lib" werde ich mich auseinandersetzen, befürchte aber eine Einschränkung und Teensy-Abhängigkeit. Kann ja sein, dass ich mal einen Arduino programmiere und die Teensy-Lib hier nicht funktioniert.
    daher mein Bestreben, möglichst allgemeingültig/universell.

    Bei meine Anwendungen wird es nicht auf die [ms] ankommen.
    Es wird in Richtung Zeitmessen, MIDI-Steuerung, etc. gehen.
    Derzeit steht nichts fest - ausser Grundlagen-Module verstehen und sameln für ein zukünftige Anwendungen.

    Pin-Interrups (später Timer-Interrupts (hiermit habe ich mich bei uC erfolgreich beschäftigt)) sind schon ein gewaltiges Werkzeug, auf das ich nicht verzichten werde.

    Um einen ISR nicht warten zu lassen, hatte ich die Idee, dass durch den Interrupt auf ein Sprungziel im loop() verwiesen wird. ISR wird nach wenigen [us] verlassen und Entprellung etc. passiert im loop().
    Geht das Überhaupt? Wenn JA, wie?
    __________________________________________________ _
    | Sprache: C | Teensy 3.2 | Arduino 2.x | Status: EwigerAnfaenger |

  6. #26
    HaWe
    Gast
    1. limitiert das Arduino API überhaupt nicht die Möglichkeiten (das hatten Mxt+ich bereits beschrieben) und
    2. geht es am einfachsten mit der Statemachine, wie ich schon erklärt habe, insb. wenn deine loop-Durchläufe nicht ewig dauern (ansonsten gäbe es auch dafür eine Lösung).
    Lies doch oben noch mal nach!

    Die ISR verweist normalerweise auf kein Sprungziel in der loop() (ist mir auch unklar, wie das überhaupt gehen könnte), aber sie kann eine globale Variable verändern ("Semaphor"), die in der loop regelmäßig abgefragt wird und wo dann je nach Wert auch entsprechend weiter gearbeitet wird (war auch schon erwähnt worden).
    (Ich selber arbeite nie mit Pin-Interrupts, sondern mit multithreading falls erforderlich oder aber notfalls auch mit timer-Interrupts, daher kann ich dir bei deinem Intr-Setup nicht weiterhelfen)

  7. #27
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    04.09.2011
    Ort
    Hessen
    Beiträge
    707
    Zitat Zitat von frabe Beitrag anzeigen
    Mit der "Teensy-Entprell-Lib" werde ich mich auseinandersetzen, befürchte aber eine Einschränkung und Teensy-Abhängigkeit. Kann ja sein, dass ich mal einen Arduino programmiere und die Teensy-Lib hier nicht funktioniert.
    daher mein Bestreben, möglichst allgemeingültig/universell.
    Nein, das ist keine spezielle Teensy Bibliothek. Die funktioniert auf allen Arduinos.


    Ein Pin-Interrupt ist was feines, wenn man damit z.B. auf Daten von einem externen IC reagiert, z.B. AD-Wandler, Netzwerk oder so. Aber bei einem prellenden Taster ist ein Pin-Interrupt doof. Wenn man da die ISR kurz hält, kommt der Interrupt beim Prellen ja immer wieder, da ist man dann wieder beim Versuch des Sperrens.

    Wenn Interrupt dann über einen Timer. Da habe ich kein Problem mit dem was Klebwax gesagt hat. Man macht im Prinzip das gleiche, was die Bounce2 Library macht. Nur das die mit millis schaut, wie lange das Signal anliegt. Bei einem Timer, der z.B. alle 0,1 oder 1 ms auslöst, kann man ja einfach zählen.

    Falls Du Bücher liest, schau mal nach "Practical UML Statecharts in C/C++". Der Mann stellt da zwar sein eigenes Framework vor, was auch ganz lehrreich ist, vergleicht es aber auch mit diversen gängigen Methoden in C und C++ Statemachines zu bauen. Insoweit eine schöne Übersicht. Im übrigen hat er die gegenteilige Meinung zu Klebwax, was die Notwendigkeit von Timern in professionellen Anwendungen betrifft und verdient auch noch Geld damit.


    Zum Entprellen eines Tasters mit einem Timer habe ich jetzt kein Beispiel, aber hier mal ein Extrakt aus einem Sketch für einen Drehgeber (Encoder). Ich habe den Code von diesem Artikel
    https://www.mikrocontroller.net/articles/Drehgeber
    umgeschrieben auf die Teensy IntervalTimer Lib:

    Code:
    constexpr int led = 13;
    constexpr int knob_SW = 2;
    constexpr int knob_DT = 5;
    constexpr int knob_CLK = 6;
    
    IntervalTimer myTimer;
    
    int encoderPosCount = 0;
    volatile int encoderDelta = 0;
    int encoderLast = 0;
    
    void encoderISR() {
      int encoderNew = 0;
    
      // convert gray to binary
      if (digitalReadFast(knob_DT)) {
        encoderNew = 3;
      }
    
      if (digitalReadFast(knob_CLK)) {
        encoderNew ^= 1;
      }
    
      int diff = encoderLast - encoderNew;
    
      if (diff & 1) {
        encoderLast = encoderNew;
        // bit 1 = direction (+/-)
        encoderDelta += (diff & 2) - 1;
      }
    }
    
    int readEncoder() {
      noInterrupts();
      
      int val = encoderDelta;
      encoderDelta = 0;
      
      interrupts();
    
      return val;
    }
    
    int readEncoder2() {
      noInterrupts();
      
      int val = encoderDelta;
      encoderDelta = val & 1;
      
      interrupts();
    
      return val >> 1;
    }
    
    int readEncoder4() {
      noInterrupts();
      
      int val = encoderDelta;
      encoderDelta = val & 3;
      
      interrupts();
    
      return val >> 2;
    }
    
    void setup() {
      pinMode(led, OUTPUT);
      pinMode(knob_SW, INPUT);
      pinMode(knob_DT, INPUT);
      pinMode(knob_CLK, INPUT);
    
      int encoderNew = 0;
      
      if (digitalReadFast(knob_DT))
      {
        encoderNew = 3;
      }
    
      if (digitalReadFast(knob_CLK)) {
        encoderNew ^= 1;
      }
    
      encoderLast = encoderNew;
    
      myTimer.begin(encoderISR, 1000);
    }
    
    void loop() {
    
      encoderPosCount += readEncoder2();
      
      // Ausgabe entfernt
      
      delay(100);
    }
    Geändert von Mxt (24.11.2019 um 16:18 Uhr)

  8. #28
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    18.03.2018
    Beiträge
    2.650
    Hallo,

    Ich habs in der Vergangenheit so gelöst:




    Code:
    
    //Arduino-Code
    //
    
    
    void setup(){
          pinMode(x,INPUT_PULLUP); //Taster 
    }
    
    
    void digitalWait(int Pin) {
      int i=8;                            //Zählervariable, 8 Durchläufe (min. 240ms Wartezeit, in Schleife, nachdem Taster losgelassen wurde)
      while(i>0) {                        
        while(!digitalRead(Pin)) {i=8;}   //Taster gedrückt, dann setze Zähler i zurück
        if (digitalRead(Pin)) {           //Taster nicht gedrückt?
          delay(30);                      //dann warte 30ms
          i--;                            //und dekrementiere den Zähler i
        }
      }
    }
    
    
    void loop(){
          if (!digitalRead(x)) {    //Ist Taster an Input x gedrückt?
                Mach_Was_Du_Machen_Sollst();
                Mach_Noch_Mehr();
                digitalWait(x);     //sicherstellen, dass Taster losgelassen wurde
          }
    }


    Vielleicht lässt sich das auf einem Teensy ähnlich machen, wenn das so ausreichend wäre.




    MfG

Seite 3 von 3 ErsteErste 123

Ähnliche Themen

  1. Teensy 3.2 +++ Interrupttimer via RTC ?
    Von frabe im Forum Arduino -Plattform
    Antworten: 1
    Letzter Beitrag: 22.10.2019, 15:56
  2. Teensy 3.2 +++ I/O-Werte, Analog-In
    Von frabe im Forum Arduino -Plattform
    Antworten: 26
    Letzter Beitrag: 18.10.2019, 09:57
  3. Der Teensy 4.0 ist fertig
    Von Mxt im Forum Arduino -Plattform
    Antworten: 44
    Letzter Beitrag: 12.08.2019, 10:24
  4. Platinenlayout Problem mit Platinenlayout - Adapterplatine für den Teensy 3.1
    Von robonooby im Forum Konstruktion/CAD/3D-Druck/Sketchup und Platinenlayout Eagle & Fritzing u.a.
    Antworten: 9
    Letzter Beitrag: 29.06.2014, 16:09
  5. Tabelle als Übergabeparameter von Subroutine?
    Von screwdriver im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 8
    Letzter Beitrag: 09.01.2009, 16:45

Stichworte

Berechtigungen

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

12V Akku bauen