Welches Bit hat einen Interrut ausgelöst?

Hallo,

ich habe ein Problem herauszufinden welches Bit den aktuellen Interrupt ausgelöst hat. Hört sich einfach an. Ist aber scheinbar nicht 100%ig sicher möglich.

Die Interrupts liegen mit insgesamt 16 Bit an 3 verschiedenen Ports an. Dazu habe ich drei ISRs, welche alle 16 Bit entsprechend verarbeiten und in 2 Bytes zusammenbasteln.

Die ersten 8 Bit werden nacheinander von externen Dartscheibenelektronik schnell im Kreis auf low getaktet. (Matrixspalten). D.h. nacheinander gehen die Bits kurz auf low und wieder high. Dann das nächste Bit. Jeder Interrupt speichert das momentane Bitmuster in einer byte-Variablen, damit später festgestellt werden kann welche Matrixspalte aktiv war. Die Wiederholfrequenz ist etwa 10 khz für ein BIt. Ein Bit ist etwa 9µs breit. Die 8 Bits sind also fast abstandslos aneinander.

Die zweiten 8 Bits sind praktisch die Reihenleitungen der Matrix. Wird einer der Kreuzungspunkte kurz geschlossen, löst einer der 8 weiteren Interupts aus. Auch hier wird das entsprechende Bitmuster in einer Variablen gespeichert und ein Interruptflag für die "loop" gesetzt.

Vor dem Speichern werden noch diverse Bit-Operationen durchgeführt um unerwünschte Sachen auszublenden bzw. die Bitmuster passend zu machen

Meine "loop" kann jetzt reagieren und mit den beiden Variablen etwas machen. In einer habe ich die Spaltennummer, in der anderen die Zeilennummer. Entsprechen zu je einem Trefferfeld auf der Dartscheibe.

Zu 95 Prozent funktioniert das auch perfekt. Aber ab und zu bekomme ich in einer der beiden Variablen einen falschen Wert. Nämlich ein höheres Bit daneben wurde erkannt.

Mit viel Aufwand bin ich jetzt drauf gekommen, dass gelegentlich eine Veränderung am Pin stattfindet die zwischen dem Triggern und dem Auslesen stattfindet.

D.h. der Signalwechsel an einem Portbit löst den entsprechenden der 3 möglichen Interrupts aus. Eine sofortige Abfrage (1. Befehl in der ISR) nach dem Byteinhalt liefert aber die Position des nächstens Pulses.

D.h. Ein Puls triggert, der Prozessor erkennt das und startet die passende ISR. Bis es zum Abfragen des PINB,C,D kommt hat sich aber das Eingangsmuster geändert und ich bekomme damit eine Spalte später als Ergebnis.

Das ließ sich ganz eindeutig nachweisen, in dem ich den PINx 2 Mal nacheinander in 2 Variable abgefragt habe. Und die habe ich vergleichen. Ab und zu gab es Unterschiede.

ISR(PCINT2_vect)                                            // Port D (Digital 0-7)
{
  byte xtemp1 = PIND ;
  byte xtemp2 = PIND ;
  if (xtemp1 != xtemp2)   Ausgabe Fehler auf seriell und Ignorieren des Restes.
  Ansonsten Byte maskieren und speichern

 snip....

Frage nun: Wie könnte ich das lösen, dass ich wirklich das Bitmuster bekomme welches den Interrupt ausgelöst hat.

Ich finde es ist keien gute Idee, da jetzt einen neuen Thread aufzumachen. So wird alles aus dem Zusammenhang gerissen. Ich habe erstmal eine Weile gebraucht, bis ich gemerkt habe, worum es geht.

Letzendlich war die Vermutung von agmue und mir dass es genau zu diesen Problem kommen würde, weshalb wird dir die Lösung mit der externen HW vorgeschlagen haben. Da diese HW die Status der Eingangsbits puffert hast Du da soche extremen Timingprobleme nicht.

Ich weis, dass Du keine externe HW einsetzen willst, aber mMn machst Du dir da das Leben unnötig schwer. Und vielleicht ist es - zumindest mit dem verwendeten Prozessor - gar nicht zu lösen. Du hast da schon sehr kritische Zeitbedingungen.

lupus1952:
Frage nun: Wie könnte ich das lösen, dass ich wirklich das Bitmuster bekomme welches den Interrupt ausgelöst hat.

Schreibe in der ISR den gesamten PIN-Port in eine Variable.
Niemals jeden PIN einzeln auslesen.
Verwende dann die Variable zur Weiterverarbeitung.
unsigned char portstateD = PIND;
Serial.println(portstateD, BIN);

my_xy_projekt:
Schreibe in der ISR den gesamten PIN-Port in eine Variable.
Niemals jeden PIN einzeln auslesen.
Verwende dann die Variable zur Weiterverarbeitung.
unsigned char portstateD = PIND;
Serial.println(portstateD, BIN);

Genau das mache ich ja. Und habe es extra ausführlich beschrieben.

MicroBahner:
Ich finde es ist keien gute Idee, da jetzt einen neuen Thread aufzumachen. So wird alles aus dem Zusammenhang gerissen. Ich habe erstmal eine Weile gebraucht, bis ich gemerkt habe, worum es geht.

Letzendlich war die Vermutung von agmue und mir dass es genau zu diesen Problem kommen würde, weshalb wird dir die Lösung mit der externen HW vorgeschlagen haben. Da diese HW die Status der Eingangsbits puffert hast Du da soche extremen Timingprobleme nicht.

Ich weis, dass Du keine externe HW einsetzen willst, aber mMn machst Du dir da das Leben unnötig schwer. Und vielleicht ist es - zumindest mit dem verwendeten Prozessor - gar nicht zu lösen. Du hast da schon sehr kritische Zeitbedingungen.

Hi,
ich habe absichtlich einen neuen Thread aufgemacht, um die Augen auf das Problem zu lenken und nicht auf irgend welchen Altballast. Das aktuelle Problem ist das Problem, dass sich PINx zwischen Auslösung des Interrupts und Abfrage des Wertes ändern können. Und ich damit den geschilderten Fehler bekomme.
Mit einem Hardware-Encoder bekomme ich zwar einen Interrupt. Habe aber das gleiche Problem, dass sich bis zum Auslesen die Bytes das schon wieder geändert haben könnten. Ich müsste also auch noch zusätzlich Hardware-Latche einsetzen. Also mindestens 2 x 8-Bit-Encoder + 1 x 6-Bit-Latch.
Beim Portexpanderboard habe ich zwar alle Bytes am Stück und muss sie nicht aus 3 Ports mit 4 Teilbytes zu 2 Variablen zusammenbasteln. Aber das gibt garantiert gewaltige Timingprobleme. Der Expander braucht ja auch verhältnismäßig viele Takte um einen Zyklus zu übertragen
Im Notfall werde ich das damit versuchen. Aber noch habe ich Hoffnung auf eine Lösung, die mit intelligenter Programmierung machbar ist. Da fehlt es mir aber noch an Erfahrung beim Arduino.

Ich werde weiter probieren und das Pferd andersrum aufzäumen. Also nicht auf die Matriyseingangsseite dauernd triggern und zu 99,99 Prozent auf einen Dart zu warten, sondern auf die Ausgangsseite und nur wenn ein Dart einen Kontakt ausgelöst hat. Und dann in 3 Zeilen sofort alle 3 Ports auslesen und in der "Loop" checken und verarbeiten.

lupus1952:
Also nicht auf die Matriyseingangsseite dauernd triggern und zu 99,99 Prozent auf einen Dart zu warten, sondern auf die Ausgangsseite und nur wenn ein Dart einen Kontakt ausgelöst hat. Und dann in 3 Zeilen sofort alle 3 Ports auslesen und in der "Loop" checken und verarbeiten.

Ne nich? Jetzt erst kapier ich, was Du da machst.
Natürlich musst Du auf das Ereignis warten und nicht das Ereignis auf Dich!

my_xy_projekt:
Ne nich? Jetzt erst kapier ich, was Du da machst.
Natürlich musst Du auf das Ereignis warten und nicht das Ereignis auf Dich!

Du hast recht. Man wartet auf ein Ereignis und handelt dann. Aber hier haben eben meine ersten Experimente noch gezeigt, dass ich oft beim Erkennen eines Treffers beim anschliessenden Auslesen des Auslösers zu spät komme. Hier geht es um µS. Und der Darttreffer komm ja nicht snychron zu irgend etwas. Wenn der Treffer ganz am zeitlichen Ende eines Matrixeingangspulses kommt, ist bis zum Auslesen des Eingangsregisters dieses vielleicht schon ein Bit weiter. Das kann ich aber nicht ohne gewaltige Timertricksereien erkennen. Der "Matrixerzeuger", also die Dartplatine, läuft auch alles andere als irgendwie gleichmäßig oder snychron. Die Pulse sind bezüglich der Breite sehr schwankend. Da sind sogar wilde Sprünge drin, wo es Impulse gibt oder nicht. Je nachdem was das DartBoard gerade macht.
Deshalb habe ich das logisch zuerst kommende Ereignis, also den Wechsel am Matrixspaltenzähler vorbeugend immer sofort bei einer Änderung ausgelesen. Und erst beim Treffer dann die Matrixausgänge und gespeicherten Spaltenzähler abgefragt welcher es denn nun war. Das klappt zu 99 Prozent. Aber das ist zu wenig. Lieber keine Ansage als immer wieder eine falsche Treffwertigkeit.
Ich werde noch mal von vorne anfangen und die ganzen Routinen umstellen.

lupus1952:
Ich werde euch bezüglich meiner aktuellen Problematik nicht weiter belästigen.

lupus1952:
... und nicht auf irgend welchen Altballast.

Du unterschätzt mein Erinnerungsvermögen.

#4 letzter Absatz könnte erfolgversprechend sein. Prellen eigentlich die Kontakte, wenn der Pfeil da reinrauscht?

lupus1952:
... nur wenn ein Dart einen Kontakt ausgelöst hat.

Nur so ginge das auch beim MCP23S17, sonst ist die Übertragung zum µC tatsächlich zu langsam.

lupus1952:
Und erst beim Treffer dann die Matrixausgänge und gespeicherten Spaltenzähler abgefragt

Über was redest Du denn eigentlich?
Wenn es tatsächlich ein Darts ist, kommen da nicht 10K Ereignisse/s zusammen, sondern vielleicht 1.
Wenn Du wissen willst, wo auf der Matrix der Einschlag ist, halte die Matrix-Steuerung in den ISR (3 Ports - 3 ISR) mit dem aktuellen Wert an.
Lese DANN die Ports aus.

my_xy_projekt:
Über was redest Du denn eigentlich?
Wenn es tatsächlich ein Darts ist, kommen da nicht 10K Ereignisse/s zusammen, sondern vielleicht 1.
Wenn Du wissen willst, wo auf der Matrix der Einschlag ist, halte die Matrix-Steuerung in den ISR (3 Ports - 3 ISR) mit dem aktuellen Wert an.
Lese DANN die Ports aus.

Ich hatte es sehr genau beschrieben was abläuft. Ich wiederhole also die ganze Sache gerne noch einmal:
Es handelt sich um ein fertiges Dartboard mit Elektronik. Dieses hat eine Treffermatrix 8x8. Ähnlich wie eine Keyboardmatrix
Die Dartelektronik adressiert der Reihe nach alle 8 Spalten mit einem Impuls. Umlauffrequenz für die 8 Spalten ca. 10 kHz
Ich habe keinen Einfluß auf die Elektronik. Deshalb kann ich da nichts anhalten. Wenn ich das Board ohne Elektronik selbst ansteuern würde wäre, das ganze kein Thema. Dazu gibt es sogar fertige Projekte.
Hier muss/will ich eben damit leben, dass jemand anders die Adressierung macht und ich keinen Einfluß habe. Ich kann quasi nur mitlesen und auswerten.
Schlägt ein Dart ein, gibt es am Kreuzungspunkt eine kurze Verbindung von der entsprechenden Spalte zu einer der 8 Reihen.
Diese Verbindung ist extrem kurz mit Prellern. Aber die interessieren nicht. Nur die erste Flanke wird beachtet. Der Rest eventueller weiterer Pulse wird ignoriert.

Um festzustellen, welches Bit welcher Reihe den Interrupt ausgelöst hat muss ich das ganze Portbyte auslesen.
Zusätzlich muss ausgelesen werden welches Bit der Spalte aktiv war. Also müssen die Ports auch ausgelesen werden.
Bei meinen inzwischen stundenlangen Experimenten habe ich festgestellt, dass die Bits an den Ports nicht gelatcht sind und sich nach dem Auslösen des Interrupts noch ändert können. Sie erster Beitrag. Eine 2-malige Portbyteabfrage unmittelbar nach dem Triggern kann verschiedene Werte haben.
Die Frage ist in Kurzform. Wie kann ich das auslösende Bit eines Portinterrupts eindeutig feststellen? Mit ein paar Gattern extern ist es wohl nicht getan. So ein 8-Encoder würde bei Prellern auch mehrfach irgendwas auslösen. Also ein Latch mit Zeitsperre. U.s.w.

Es gibt auch neuere 32 Bit Prozessoren mit mehr externen Interrupts

Auch der Atmega2560 hat eigentlich 8 Interrupts. Auf dem Arduino Board sind da leider nur 6 verfügbar:
https://www.arduino.cc/en/Hacking/PinMapping2560 (siehe Pins 8 und 9)

Es gibt aber auch Platinen bei deinen man an alle Pins kommt. Z.B. sowas: ARD MEGA2560 PRO: Arduino kompatibles Mega 2560 Pro Board bei reichelt elektronik

EDIT:
Wobei du sowie es aussieht 16 Interrupts willst. Dafür bräuchte man einen der 32 Bit Prozessoren wo jeder Pin einen eigenen Interrupt Vektor hat:

lupus1952:
So ein 8-Encoder würde bei Prellern auch mehrfach irgendwas auslösen.

Nein, der von agmue vorgeschlagene Baustein wird nur einmal beim ersten Puls speichern. Dann ist der Latch gesperrt, bis Du den vom Prozessor aus ausgelesen hast. Du solltest dich mal mit dem Datenblatt vom MCP23S17 beschäftigen.

Hallo,

ich finde das auch etwas dümmlich mit dem extra Thread. Denn als extra Thread fehlen eine Menge an Informationen. Das ist alles ohne jeden Zusammenhang. Muss ich so sagen wie es ist.

Ich kann nur zum PCINT des µC etwas sagen und dessen Interrupt. Einen MCP kann ich hier nicht herauslesen.
Du musst gleich zu Begin in der ISR Register PINx auslesen und dir merken. Danach kannste in Ruhe durchtesten welches Bit davon gesetzt ist. Dafür musste dich mit Bit Operationen befassen.

Doc_Arduino:
Hallo,

ich finde das auch etwas dümmlich mit dem extra Thread. Denn als extra Thread fehlen eine Menge an Informationen. Das ist alles ohne jeden Zusammenhang. Muss ich so sagen wie es ist.

Ich kann nur zum PCINT des µC etwas sagen und dessen Interrupt. Einen MCP kann ich hier nicht herauslesen.
Du musst gleich zu Begin in der ISR Register PINx auslesen und dir merken. Danach kannste in Ruhe durchtesten welches Bit davon gesetzt ist. Dafür musste dich mit Bit Operationen befassen.
Arduino Reference - Arduino Reference

Also extra für dich: Alles, was zu dem Thema nötig ist, steht im ersten Post von mir. Und es fehlt nichts, was zum Thema erorderlich wäre! Du müsstest ihn einfach komplett lesen und verstehen.
Dann habe ich es danach bereits noch einmal ausführlicher beschreiben. Es ist alles(!) an Information vorhanden, was zum Beantworten meiner Frage nötig ist. Deine Bemerkung dazu finde ich genauso dümmlich wie du meinen Threadwechsel. Oder noch dümmlicher. :frowning:
Dein Vorschlag das Byte am Anfang der ISR zu lesen ist genau mit dem Problem verbunden. Aber das hast du geflissentlich überlesen. Wie manche andere auch. Aber genau dort steckt das Problem.
Wozu schreibe ich eigentlich alles so präzise wie möglich und nötig?
Zum letzten Mal nun:
Ein wechselndes Bit am Port x löst den Interrupt aus. Der Atmel erkennt das und startet die zugehörige ISR. Dort frage ich als Erstes das entsprechende Port-Byte ab. Und bekomme ab und zu falsche Werte weil, das anliegende Byte zwischen Erkennen des Interrupts durch den Atmel und meiner Abfrage in der ISR schon verändert wurde. Als Beispiel habe ich im ersten Post, den du wohl übersehen hast, das sogar mit einem Codeschnipsel gezeigt. 2 solche PINx Abfragen nacheinander bringen sporadisch verschiedene Werte. Also ein anderer Wert als der, der den Interrupt ausgelöst hat.

Hallo,

okay, ich spiel das Spiel mit.
Stellen wir uns einmal ganz dumm und behandeln den Thread als Alleinigen.
Wo nimmst deine besagten 16 Bits her?
Bei mir hat 1 Port 8Bit und 3 Ports zusammenbetrachtet 24Bit.
Ich weiß im Grunde genommen auch nicht welchen Controller du hast. Deswegen könnte die Annahme der 8Bit pro Port auch falsch sein. Ich weiß auch nicht was du mit den 16Bits machen möchtest.
Verstehste?
/* Spielende *\

Du musst dich nicht nach unseren Regeln richten. Du musst dich nach den allgemeinen Forenregeln richten. Niemand kann im Forum deinen Tisch, deinen Bildschirm sehen oder deine Gedanken lesen.

Da ich und andere aber nicht auf dem Kopf gefallen sind, sehen wir was du eigentlich machen möchtest, nur deshalb bekommste hier überhaupt Antworten. Wir müssen von dir nicht wissen wie der Controller arbeitet. Wir benötigen Informationen für das drum herum, dass was außerhalb des Controllers passiert. Zum Bsp. wäre ein Timingdiagramm der Signale nicht verkehrt, wenn es denn so zeitkritisch ist. Würde deinen Text dazu besser veranschaulichen.

Das Interruptsignal muss eine Mindestlänge von paar Takten haben. Ansonsten ist das tatsächlich wieder weg zwischen Interrupterkennung und in die ISR springen um das PINx Register auslesen. Wie lang ist der minimale Impuls? Sind das die 9µs? Das entspricht 144 Takte für High Pegel. Wenn dem so ist, reicht das aus. Sind das pro Bit 9µs High und dann 9µs Low Pegel? Wenn dagegen die Signalperiode nur 9µs lang ist, dann wirds echt knapp. Wieviel davon ist dann der High Pegel lang?

Dann musste wie schon geschrieben PINx auslesen und mittels Bit Operatoren vergleichen.
Mehrfach auslesen hilft dir dabei nicht. Du willst ja nicht wissen obs wieder weg ist, du willst wissen welches Bit oder gar Bits im gesicherten Byte drin stecken. Dafür benötigst du besagte Bit Operationen.

Desweiteren gibt dein Code nicht viel her. Was machst du mit der gewonnen Information aus der ISR, wenn sie denn irgendwann einmal klappt? Dabei gehts mir um bestimmte Dinge die ich nicht sehen kann um sie zu prüfen.

Trotz deiner Trotzigkeit helfe ich dir mal weiter. Wir müssen es ja nicht ausarten lassen. Die angenommenen 144 bzw. vielleicht nur 72 Takte reichen locker zur Pegelerkennung und um in die ISR zu springen und den Zustand zu speichern. Sie reichen aber nicht unbedingt aus um aufwendige Bit Operationen auszuführen. Du müßtest ja pro Port 8 Vergleiche machen. Dann kann es durchaus sein das eine nächste Pegelerkennung schief geht. Der nächste Interrupt wird zwar angesprungen, aber bis wirklich PINx ausgelesen wird kann der anliegende Puls schon wieder weg sein. Müßte man wenn man es genau wissen will ausmessen.
Deswegen, um dem Signalverlust vorzubeugen, darfste von den Ports in der ISR nur PINx jeweils auslesen und erst am Ende, wenn alles vorbei ist, kannste alle 3 gespeicherten Bytes in Ruhe außerhalb jeder ISR auswerten. Wie gesagt mit Bit Operationen. Woher du Anfang und Ende der Signalerzeugung nimmst weiß ich nicht. Ich weiß nicht was die Dartscheibe an Signalen bietet.

Für all das brauchste noch volatile Variablen, da bin ich mir sicher. Wenn der Datenaustausch zwischen Hauptprogramm und ISR sich nur auf einzelne Byte bezieht, brauchste dich um atomaren Zugriff nicht kümmern. Ansonsten benötigst du das auch noch.

Für das Problem des Signalverlustes, weil möglicherweise zu kurz, gabs im alten Thread auch schon andere Ideen.

Jetzt rollt der Ball wieder zu dir.

Ihr vergesst bei den ganzen Zeitbetrachtungen aber, dass der Prozessor ja nicht nur einfach auf diesen Interrupt wartet. Der macht auch noch andere Sachen - z.B. für die millis(). Das ist nämlich auch ein Interrupt, und wenn der gerade aktiv ist während der Impuls kommt ist es nichts mit der schnellen Reaktion.

Doc_Arduino:
Hallo,

okay, ich spiel das Spiel mit.

Ich empfinde es langsam als Trauerspiel!

Stellen wir uns einmal ganz dumm und behandeln den Thread als Alleinigen.

Das wäre schön, wenn das endlich mal jemand machen würde! Statt dessen wird auf Sachen rumgehackt, die nicht zum Frageposting gehören. Auch du bist gemeint. Du hast dir jetzt riesige Mühe für ein großes Posting gemacht. Aber davon sind 75 Prozent OT. Weil sie sich ums Drumherum bewegen, statt konkret die klar definierte Frage zu beantworten

Wo nimmst deine besagten 16 Bits her?

Gehört zwar nicht zum Thema. Die 16 Bit kommen aus der Boardmatrix einer elektronischen Dartscheibe. Die möchte ich parallel auslesen.

Bei mir hat 1 Port 8Bit und 3 Ports zusammenbetrachtet 24Bit.

Komisch - bei mir auch

Ich weiß im Grunde genommen auch nicht welchen Controller du hast. Deswegen könnte die Annahme der 8Bit pro Port auch falsch sein.

Arduino UNO R3

Ich weiß auch nicht was du mit den 16Bits machen möchtest.

Habe ich nun bereits mehrfach erklärt

Verstehste?
/* Spielende *\

Trauerspiel! Viel "off Topic!" bezüglich der Ursprungsfrage!

Du musst dich nicht nach unseren Regeln richten. Du musst dich nach den allgemeinen Forenregeln richten. Niemand kann im Forum deinen Tisch, deinen Bildschirm sehen oder deine Gedanken lesen.

Ich weiß wie man in Foren umzugehen hat. Leider gibt es, und ganz speziell in deutschen, Foren immer wieder Leute, die sich gar nicht die Mühe machen eine Frage zu lesen und zu verstehen. Die antworten dann irgendwas mehr oder weniger Brauchbares drumherum. Aber nicht zum Kern der Frage. So auch in diesem Fall. Ich nenne keine Namen. Aber bei ein paar Leuten ist genau das der Fall. Zum Teil auch bei dir. Das muss ich leider sagen. Du fragst mich hier Sachen, die ich ein paar Posts zuvor erklärt habe. So etwas nervt nur und man fühlt sich nicht ernst genommen.

Da ich und andere aber nicht auf dem Kopf gefallen sind, sehen wir was du eigentlich machen möchtest, nur deshalb bekommste hier überhaupt Antworten.

Oh . wie gütlich. Muss ich jetzt auf die Knie gehen? Soll ich mich bedanken dafür, dass mir viele der unnötigen Antworten meine Zeit stehlen und ich immer wieder das zuvor gesagte nochmal wiederholen muss?
Ich sage danke zu denen, die sich die Mühe gemacht haben wirklich konkret zu helfen. Z.B. mit den Hardwaretips.

Wir müssen von dir nicht wissen wie der Controller arbeitet. Wir benötigen Informationen für das drum herum, dass was außerhalb des Controllers passiert.

Ausserhalb des Controllers ist die Dartmatrix! Habe ich aber schon beschrieben!

Zum Bsp. wäre ein Timingdiagramm der Signale nicht verkehrt, wenn es denn so zeitkritisch ist. Würde deinen Text dazu besser veranschaulichen.

Zu den Zeiten habe ich mich bereits sehr ausführlich geäußert!

Das Interruptsignal muss eine Mindestlänge von paar Takten haben. Ansonsten ist das tatsächlich wieder weg zwischen Interrupterkennung und in die ISR springen um das PINx Register auslesen. Wie lang ist der minimale Impuls? Sind das die 9µs? Das entspricht 144 Takte für High Pegel. Wenn dem so ist, reicht das aus. Sind das pro Bit 9µs High und dann 9µs Low Pegel? Wenn dagegen die Signalperiode nur 9µs lang ist, dann wirds echt knapp. Wieviel davon ist dann der High Pegel lang?

Super – es geht ja auch konkret.. Nur leider nicht konkret zu meiner Anfangsfrage! Es nützt nichts wenn du oder andere mir viel vom Drumherum erklären und ich eine spezielle Einzelfrage gestellt habe

Dann musste wie schon geschrieben PINx auslesen und mittels Bit Operatoren vergleichen.

Dass ich das genau so mache habe ich bereits mehrfach geschrieben. Aber das passt nicht zur Frage!

Mehrfach auslesen hilft dir dabei nicht. Du willst ja nicht wissen obs wieder weg ist, du willst wissen welches Bit oder gar Bits im gesicherten Byte drin stecken. Dafür benötigst du besagte Bit Operationen.

Das Mehrfachauslesen war ein Testfall! Der mir gezeigt hat, dass zwischen den Zeitpunkten des Auslösen des IRQ bis zum Abfragen des Ports, sogar zwischen 2 Folgeabfragen, der Eingangswert sich gelegentlich ändert. Und somit falsche Ergebnisse rauskommen. Aber auch das habe ich bereits gesagt

Desweiteren gibt dein Code nicht viel her.

Wozu auch? – es war nur ein Test zum Erkennen des Problems

Was machst du mit der gewonnen Information aus der ISR, wenn sie denn irgendwann einmal klappt?

Was ich damit mache ist bezüglich meiner Frage egal. Aber ich sage auch das nochmal: Ich möchte die Treffer in einer Dartscheibe protokollieren. Bitte dazu aber keine weiteren OT-Antworten

Dabei gehts mir um bestimmte Dinge die ich nicht sehen kann um sie zu prüfen.

Da gibt es nichts zu sehen und zu prüfen! Ich wollte eigentlich nur eine Antwort auf meine Frage. Und keine Romane drumherum.

Trotz deiner Trotzigkeit helfe ich dir mal weiter.

Auch typisch für deutsche Foren ist das Beleidigen der Fragesteller. Der eine bezeichnet mein Handeln mit dem zweiten Thread als dümmlich. Du betitelst mich als trotzig!

Wir müssen es ja nicht ausarten lassen.

Schön – dann kommen wir mal auf den Punkt

Die angenommenen 144 bzw. vielleicht nur 72 Takte reichen locker zur Pegelerkennung und um in die ISR zu springen und den Zustand zu speichern.

Aber nachweislich bekomme ich für einen Interrupt bei 2 direkten (Test-) Folgeabfragen ab und zu unterschiedliche Werte. Natürlich auch bei nur einer Abfrage. Bloß da war das Erkennen des Fehlers schwer. Es ist mir halt nur dadurch aufgefallen, weil mache Ergebnisse unlogisch waren. Deshalb bin ich auf die Suche gegangen.

Sie reichen aber nicht unbedingt aus um aufwendige Bit Operationen auszuführen. Du müßtest ja pro Port 8 Vergleiche machen.

Zum Glück nicht. Von der Matrix ist immer nur eine Spalte und eine Reihe gleichzeitig aktiv. Nach Erkennen eines Interrupts werden in der Loop dann die Bits und Bytes maskiert und/oder geschoben. Als Ergebnis habe ich 2 Variable. Einmal Spalte, einmal Reihe mit je einem gesetzten Bit. Das funktioniert alles.

Dann kann es durchaus sein das eine nächste Pegelerkennung schief geht. Der nächste Interrupt wird zwar angesprungen, aber bis wirklich PINx ausgelesen wird kann der anliegende Puls schon wieder weg sein. Müßte man wenn man es genau wissen will ausmessen.

Ich habe stundenlang scopiert und unzählige Testsscripte dazu gemacht. Das Auswerten der Bits, wenn ich erst mal so ein Portbyte habe, erfolgt in der Loop. Diese erkennt per entsprechender Flags, dass ein neues Byte da ist. Und solange werden keine Interrupts mehr angenommen bzw. gesperrt. Zwischen Darttreffern habe ich mehr als genug Zeit zum Auswerten. Wichtig ist nur, dass ich exakt den Zustand beim Treffereinschlag in das zu lesende Portbyte bekomme. Sie Ursprungsfrage.

Deswegen, um dem Signalverlust vorzubeugen, darfste von den Ports in der ISR nur PINx jeweils auslesen und erst am Ende, wenn alles vorbei ist, kannste alle 3 gespeicherten Bytes in Ruhe außerhalb jeder ISR auswerten. Wie gesagt mit Bit Operationen.

Genauso mache ich das. Habe ich aber schon geschrieben

Woher du Anfang und Ende der Signalerzeugung nimmst weiß ich nicht. Ich weiß nicht was die Dartscheibe an Signalen bietet.

Es gibt kein Anfang und Ende! Die Matrix wird permanent im "Kreis herum" von der Dartelektronik "gescannt" Habe ich aber schon ausführlich erklärt. Und spielt bezüglich meiner Ursprungsfrage eigentlich keine Rolle.
An Signalen bekomme ich die Matrixspalten und Matrikreihen. Deren Pegel überwache ich. Das sind 2 x 8 Bit. Habe ich aber auch schon erklärt

Für all das brauchste noch volatile Variablen, da bin ich mir sicher. Wenn der Datenaustausch zwischen Hauptprogramm und ISR sich nur auf einzelne Byte bezieht, brauchste dich um atomaren Zugriff nicht kümmern. Ansonsten benötigst du das auch noch.
Für das Problem des Signalverlustes, weil möglicherweise zu kurz, gabs im alten Thread auch schon andere Ideen.

Ich weiß, Hardware extern. Das waren auch damals die wenigen sachlich guten zum Thema passenden Antworten. Nur leider entweder nicht einfach umsetzbar oder mir zunächst zu aufwendig. Ich bin mir sicher, dass es per Software machbar ist.

Jetzt rollt der Ball wieder zu dir.

Ich habe aber keine Lust mehr zu spielen. Ich probiere noch ein paar Varianten in der Abfrageoptimierung meines bisher laufenden Scriptes.
Und notfalls kommen 2 Hardware 8>3 Interruptencoder an die Matrix und einen Latch-Baustein.
Danke für deine ausführliche Bemühung

lupus1952:
Ich bin mir sicher, dass es per Software machbar ist.

Und ich bin mir ebenso sicher, dass es - zumindest auf einem UNO - nicht rein per Software machbar ist. Du wirst sporadisch immer wieder was verlieren, weil dir andere Interrupts in die Quere kommen.

Du müsstest den 386P von Grund auf selbst programmieren um sicher zu sein, dass dir nichts in die Quere kommt. Oder zumindest den millis() Interrupt abschalten und nichts anderes aktivieren, was Interrupts braucht oder sie - und sei es noch so kurz - unterdrückt.

lupus1952:
Diese Verbindung ist extrem kurz mit Prellern. Aber die interessieren nicht. Nur die erste Flanke wird beachtet. Der Rest eventueller weiterer Pulse wird ignoriert.
...
Bei meinen inzwischen stundenlangen Experimenten habe ich festgestellt, dass die Bits an den Ports nicht gelatcht sind und sich nach dem Auslösen des Interrupts noch ändert können.

Wenn stimmt, was Du schreibst, könnte hier Dein Gedankenfehler liegen: Interrupt wird ausgelöst → Kontakt prellt → Port wird falsch eingelesen.

Hast Du einen LA? Dann kannst Du messtechnisch Die Zeit vom Inerruptauslösenden Impuls bis zum Lesen in der ISR verfolgen. Das Setzen eines Port-Pins über direkte Portbefehle geht sehr schnell, das kannst Du auch in der ISR direkt vor oder nach dem Einlesen des Dart-Ports machen. Dann kannst Du da direkt erkennen, was Du liest und wie die Abläufe sind.