Überschneidung von ISR

Hi, ich habe einen Sketch, in dem eine Timer-ISR abläuft. Diese ist relativ lang. Jetzt möchte ich wissen wie man messen kann, wie lang diese ist. ich habe Angst, dass sich zwei aufeinanderfolgende ISRs überschneiden. Ich möchte relativ hohe Taktraten verwenden und nur wenige Mikrosekunden zwischen Schritten warten, da ich Schrittmotoren ansteuern werde, die mit 1000 Umdrehungen pro Minute laufen sollen. Vielen Dank

Du könntest am Anfang und Ende der ISR die micros() in volatile unsigned long Variablen schreiben und die im Loop auswerten.

Besser ist aber genau zu schauen, was noch aus der ISR raus kann. In der ISR sollte man nur Statusvariablen setzen, evtl. Zähler und raus. Die Auswertung und Berechnungen gehören in den Loop.

Gruß Tommy

Ja das stimmt. Aber ich habe den Schrittmotor in der ISR anzusteuern. Und die live Berechnung wird mit einem Bresenham durchgeführt. Da muss etwas mehr hinein.

1000u/min das sind 16,7Hz. Wieviele Schritte pro Umdrehungen hat Dein Motor?

Grüße Uwe

Grumm_HD:
Aber ich habe den Schrittmotor in der ISR anzusteuern.

Sagt wer?

An Whandall

Im loop() wird der Gcode verarbeitet. Die Schritte sollen in Echtzeit gemacht werden. Da ich im loop alle Daten verarbeite und buffere. Der Code ist noch nicht fertig und sehr unübersichtlich, deshalb kann ich noch nichts zeigen.

An Uwefed: zur Zeit sind es 400 Schritte. es werden aber noch mehr, da ich eine bessere Laufruhe der Schrittmotoren haben möchte. außerdem kommen noch Rampenberechnungen dazu.

An Tommy: mit micros ist es gar keine Schlechte Idee. wobei ich mir da nicht sicher bin, ob micros auch während einer ISR läuft. Ich kenne die Prioritäten des Atmega nicht.

An alle: wieso darf ich nur alle 5 Minuten senden? Okay wegen Spam, aber ist es nicht irgendwann so, dass man nicht mehr diese Begrenzung hat?

Grumm_HD: Im loop() wird der Gcode verarbeitet. Die Schritte sollen in Echtzeit gemacht werden. Da ich im loop alle Daten verarbeite und buffere.

Du bekommst das beste Echtzeitverhalten, wenn du ohne blockierenden Kode und mit minimaler ISR arbeitest.

Micros steht während der ISR, wenn man nicht explizit die Interrupts wieder enabled, wovon in aller Regel abzuraten ist.

Die Priorisierung der Interrupts bezieht sich nur auf die Reihenfolge der Ausführung bei gleichzeitiger Aktivität, höher priorisierte Irqs unterbrechen eine laufende ISR niedrigerer Priorität nicht.

Nach 100 Posts kannst du so schnell posten wie du willst (glaube ich jedenfalls). ;)

Hier ist die ISR einmal in der Rohfassung. Sie wird noch länger. meint ihr,dass man diesen Code mit 30 Kilohertz ausführen kann?
Vielen Dank
Das sollte doch Echtzeitverhalten sein. Nicht wahr?

ISR.txt (1.43 KB)

Dein Kode sieht (etwas lesbarer formatiert) so aus

ISR(TIMER1_COMPA_vect) {
  i++;
  if (cx >= ISRX || cy >= ISRY || cz >= ISRZ) {
    ISRX = input_line[Read_Pointer][0];
    ISRY = input_line[Read_Pointer][1];
    ISRZ = input_line[Read_Pointer][2];
    ISRPAUSE = input_line[Read_Pointer][3];
    dir = input_line[Read_Pointer][4];
    cy = 0;
    cx = 0;
    cz = 0;
    if (Read_Pointer >= CBufflength) {
      Read_Pointer = 0;
    } else {
      Read_Pointer++;
    }
  } else if (timer_var == true) {
    switch ( dir) {
      case 1:
        fy = fy - dy;
        fz = fz - dz;
        if ( fy <= 0 && dy > 0)         {
          iy++;
          fy = fy + dx;
        }
        if  (fz < 0 && dz > 0) {
          iz++;
          fz = fz + dx;
        }
        break;
      case 2:
        fx = fx - dx;
        fz = fz - dz;
        if ( fx <= 0 && dx > 0)      {
          ix++;
          st(stpx, sx, Feedrate1, sttpx);
          fx = fx + dy;
        }
        if  (fz < 0 && dz > 0) {
          iz++;
          st(stpz, sz, Feedrate1, sttpz);
          fz = fz + dy;
        }
        break;
      case 3:
        fx = fx - dx;
        fy = fy - dy;
        if (fx <= 0 && dx > 0) {
          ix++;
          st(stpx, sx, Feedrate1, sttpx);
          fx = fx + dz;
        }
        if (fy < 0 && dz > 0) {
          iy++;
          st(stpy, sy, Feedrate1, sttpy);
          fy = fy + dz;
        }
        break;
    }
  }
}

Ohne den ganzen Rest des Programms, speziell die Definitionen aller Variablen und der Funktion st kann man deine Frage nicht beantworten.

Ich sehe in dem Kode nichts was in der ISR gemacht werden müsste,
Flag setzen und in loop bearbeiten wäre da meiner Ansicht nach angesagt.

Mit deiner Technik werden fast alle Variablen volatile und extrem schwer im restlichen Programm zu manipulieren.
Dir ist bewusst, dass jeder Zugriff auf volatile Variablen (länger als ein Byte) außerhalb der ISR nur bei abgeschalteten Interrupts erfolgen darf?

So, nach langer Zeit kann ich antworten. In der Interruptroutine werden die Schritte gemacht: Siehe st(). st wurde übrigens in einer neueren Version aus dem Programm geworfen. Ich kann mal versuchen den ganzen Code aus Atmel Studio 7 zu exportieren. Ich werde es dann in einer Zip datei Hochladen.

Ich habe den Code nun vollständig in einer Zip Datei hochgeladen:

CNC with RTMzipped.zip (6.31 KB)

Whandall: Dir ist bewusst, dass jeder Zugriff auf volatile Variablen (länger als ein Byte) außerhalb der ISR nur bei abgeschalteten Interrupts erfolgen darf?

Nein, liegt das daran, dass sie sonst zerhackt werden könnten? Oder wie sieht das mit ihnen aus. und eben die Interrupts auszuschalten sollte doch nicht so schwer sein... Vielen Dank für den Hinweis