Wie genau ist das Timing von pulsIn ()?

8

Ich habe die pulseIn()Funktion zur Verarbeitung der PWM-basierten Binärdatencodierung verwendet. Es eignet sich gut zur Unterscheidung von Impulsen mit signifikant unterschiedlichen Längen, z. B. 500us gegenüber 1500us. Damit ist es mehr als ausreichend für die Handhabung typischer IR-Fernbedienungen.

Ich möchte jedoch mein eigenes IR-System erstellen, das mehr als 2 Pulslängen verwenden kann, damit die Datenübertragung schneller erfolgen kann. Idealerweise möchte ich 8 verschiedene Pulslängen für die Oktalcodierung verwenden (z. B. 200us, 400us, 600us usw.).

Ich habe jedoch erhebliche Abweichungen bei den zurückgegebenen Werten festgestellt pulseIn()(+/- 10%). Ich gehe davon aus, dass zumindest ein Teil davon von den IR-Sende- und Empfangsmodulen eingeführt wird, aber ich habe nicht genügend Ausrüstung, um dies zu überprüfen.

Angenommen, ich kann diesen externen Fehler abmildern, ist er pulseIn()wahrscheinlich genau genug, um solche ähnlichen Impulse zu unterscheiden?

Peter Bloomfield
quelle

Antworten:

11

Die Funktion pulsein () ist sehr verlustbehaftet, da es sich um eine harte Schleife handelt und eine Zahl * der angenommenen Taktzyklen zurückgibt, die pro Schleife benötigt werden

...
// wait for the pulse to stop
while ((*portInputRegister(port) & bit) == stateMask) {
  if (numloops++ == maxloops)
    return 0;
  width++;
}

// convert the reading to microseconds. The loop has been determined
// to be 20 clock cycles long and have about 16 clocks between the edge
// and the start of the loop. There will be some error introduced by
// the interrupt handlers.
return clockCyclesToMicroseconds(width * 21 + 16); 

Die genaueste Methode zum Erfassen des Timings einer PIN ist die INPUT CAPTURE FEATURE. Schauen Sie sich dieses Beispiel an . Es ermöglicht die Erfassung des Eingangs bei 1x CPU für maximale Auflösung und jede Flanke des Eingangspins erfasst den Taktwert des Timers zum Lesen aus dem generierten Interrupt-Dienst. Es ermöglicht auch die Erfassung des Timer-Überlauf-Interrupts, um eine große absolute Zeit aufrechtzuerhalten. Da rollt der 1x ziemlich schnell. Die Captures speichern die Zeit in einem Array zum Lesen durch die Hauptschleife.


Wo für Signale über IR die typische Bibliothek die Shirriff / Arduino-IRremote- Bibliothek ist. Wo es mehrere Demos gibt, die das IR von einem demodulierten Signal lesen und senden. Damit man eine Skizze seines eigenen Designs erstellen kann. Dieser Code erstellt ursprünglich einen Timer-Interrupt, der den Eingangs-Pin mit einer durch festgelegten Rate abfragt

#define USECPERTICK 50  // microseconds per clock interrupt tick

in der Datei IRremote.h. Für meine Zwecke habe ich es auf 25 us geändert. Wo ich das noch finde, können zeitweise Pulsströme fehlen.

Beachten Sie, dass die Demodulation am besten innerhalb des IR-Empfängers durchgeführt wird, der seinerseits dieses interessierende Signal ausgibt. Wo man Hintergrundinformationen hinzufügt. Bei Verwendung der typischen 38-kHz-Modulation entspricht dies einer Mindestauflösung von 26,3 uS pro Impulszyklus. Die Bibliothek von Sheriff zeigt, dass die meisten Bauds oder Bits in der Größenordnung von mehr als 10 Impulsen liegen. Welche scheinen Ihre gewünschten Zeiten zu erfüllen.

Microtherion / Arduino-IRremote- Gabel von Shirriffs Arbeit verbessert den Empfang, indem die Timer-Interrupt-Abfrage des Pins durch die Verwendung von PinChangeInterrupts ersetzt wird. Was ich in meine eigene mpflaga / Arduino-IRremote- Gabel integriert habe, die mehrere andere Funktionen hinzufügt.

Sie können also jede der oben genannten Bibliotheken verwenden. Oder erstellen Sie Ihre eigene App, die eine der folgenden Methoden zum Erfassen von Kanten verwendet.

  1. Umfragen zu einem Timer-Ereignis (z. B. 50uS)
  2. erfasst die micros () auf einem PinChangeInterrupt
  3. verwendet Input Capture Interrupts, um die genaue Zeit zu ermitteln
mpflaga
quelle
1
Geniale Antwort. Die Arduino-IRremote ist eine sehr hochwertige Bibliothek. Leicht lesbar und hat viel durchdachtes Design, was bedeutet, dass es sehr zuverlässig ist.
Cybergibbons
2

Hier finden Sie einige Testdaten eines pulseInTests. Ein Arduino sendete angeblich 14us-Impulse, der andere spuckte diese Daten aus:

18,18,18,12,18,18,18,18,18,18,18,18,18,18,18,18,18,24,19,18,18,18,18,18,24, 18,18,18,19,18,18,12,18,18,19,18,18,18,18,18,18,18,18,18,18,18,19,18,19,24, 18,18,18,18,18,18,18,24,18,18,18,18,18,18,18,18,18,18,18,18,18,19,18,18,18, 18 18,18,18,18,18,18,18,19,18,18,18,11,18

Wie Sie sehen können, sind die Impulse keineswegs genau. Die Zeit wäre genauer, wenn die Sende- und Empfangsende in Assembly geschrieben oder sogar auf ihre eigenen Prozessoren ausgelagert würden.

Der Doktor
quelle