Wieviele Interrupts verträgt ein Arduino?

Ich versuche gerade, die SoftwareSerial bzw. AltSoftSerial Bibliothek zu verbessern. Bei einer exakten Emulation einer Hardware-UART müßte das Eingangssignal (Rx) eigentlich mit der 16-fachen Baudrate abgetastet werden, Bei 115kBaud wären das stolze 1,8 MHz (550ns), d.h. 8 CPU Takte, und das geht sicher schief. Selbst bei 4-facher Abtastung wären es noch 460kHz (2µs), wohl auch noch zu viel. Die IRremote Bibliothek arbeitet mit 20kHz (50µs), das scheint also noch zu funktionieren. Vierfache Abtastung von 9600 Baud wären dann etwa 40kHz, könnte das noch funktionieren? Hat jemand eine Idee, wie hoch man insgesamt gehen könnte, ohne den Controller komplett lahmzulegen?

Ein anderer Ansatz wäre der InputCompare Interrupt, der nur bei einem Wechsel des Eingangssignals auftritt. Damit hätte man maximal einen Interrupt pro Bit. Das wären bei 115kBaud immer noch bis zu 115kHz, aber bis 38kBaud könnte das noch funktionieren?

Ich versuche gerade, die SoftwareSerial bzw. AltSoftSerial Bibliothek zu verbessern

Die AltSoftSerial habe ich mir mal angesehen.
Da wird auf jeden Fall nicht "mit16-facher Baudrate abgetastet", sodern ein Timer zur (einfachen) Abtastung verwendet.
Zum Senden wird die CPU nur bei Flankenwechsel benutzt und das richtige Timing über Hardware realisiert.

Was willst du übrigens verbessern?

Die maximale Baudrate von Interrupt-gesteuerten Software Serial Varianten hängt davon ab wie viele Interrupts der Rest des Systems produziert.

Dein Gedankengang erinnert an das Shannon Theorem. Das ist aber falsch. Der Timer verwendet den Compare Interrupt für das Senden und den Input Capture Interrupt für das Empfangen. Das wird nichts mit höheren Frequenzen abgetastet. Das Limit entsteht AVR typisch dadurch dass sich Interrupts nicht gegenseitig unterbrechen können.

Mit der Analyse der Bibliotheken bin ich bei den Timer-Makros hängen geblieben, und mußte mich erst mal mit den Timern vertrauter machen. Erst beim Nachrechnen bin ich dann über die riesigen Interrupt-Raten gestolpert, die dabei auftreten können - je nach Ansatz. Die haben dann auch meine Idee von einer Emulation mehrerer Kanäle zu Fall gebracht :frowning:

Zudem wollte ich die Anbindung an einen bestimmten Timer (T1) loswerden, da der auch schon von anderen Bibliotheken verwendet wird, gerade wegen seiner speziellen Interrupts. Dazu fehlt mir noch eine Liste, welche Standardfunktionen (analogWrite, tone, pulseIn, shiftIn/Out, Servo, SPI...) welche Timer benutzen.

Mit Shannon hatte ich eigentlich nichts am Hut, ich wußte nur daß die Hardware UARTs (8051...) das Signal mit 16-facher Baudrate arbeiten, und das Eingangssignal in der Mitte des Zeitrahmens abtasten. Das macht so eine Übertragung sehr tolerant gegenüber abweichenden Frequenzen auf der Sender- und Empfängerseite. Deshalb kam ich auf die minimal vierfache Interruptrate, mit einer Unsicherheit von 1/4 bei der Erkennung des Startbits, und der Verschiebung um 2 Takte (halbes Bit) für die mittige Abtastung des Signals. Das wäre IMO die Voraussetzung für eine zuverlässige Abtastung mehrerer Eingänge, ohne Verwendung spezieller Timer-Features.

Die Timer-Interrupts könnten ausgeschaltet werden, solange nichts übertragen wird, und würden dann das System nicht weiter belasten. Diese Idee könnte jedenfalls auch in der IRremote Bibliothek verwendet werden, die ja bei manueller Bedienung die meiste Zeit nichts zu tun hat. Diese Bibliothek lasse ich jedenfalls beim Streß-Test eines Programms gerne mitlaufen.

Jetzt habe ich mir SoftwareSerial näher angeschaut, der Code ist etwas gruselig. Dabei stört mich, daß der Controller während des Sendens und Empfangens komplett lahmgelegt wird, Also eher nicht gut für anspruchsvolle Programme :frowning:

Bei AltSoftSerial habe ich schon mehrere Verbesserungsmöglichkeiten gefunden, insbesondere beim Versenden gleicher Bits. Das scheint zwar angedacht zu sein, wird aber durch die Implementierung verhindert. An einigen Stellen verstehe ich noch nicht, wie das überhaupt funktionieren kann. Mal sehen...