Vraag:
Hoe nauwkeurig is de timing van pulseIn ()?
Peter Bloomfield
2014-02-20 17:03:18 UTC
view on stackexchange narkive permalink

Ik heb de functie pulseIn () gebruikt voor het verwerken van op PWM gebaseerde binaire gegevenscodering. Het werkt goed voor het onderscheiden van pulsen die significant verschillende lengtes hebben, b.v. 500us versus 1500us. Dat maakt het meer dan voldoende voor het hanteren van typische IR-afstandsbedieningen.

Ik wil echter mijn eigen IR-systeem maken dat meer dan 2 pulslengten kan gebruiken, zodat de gegevensoverdracht sneller kan plaatsvinden. Idealiter zou ik 8 verschillende pulslengten willen gebruiken voor octale codering (bijv. 200us, 400us, 600us, enz.).

Ik heb aanzienlijke variaties opgemerkt in de waarden die worden geretourneerd door pulseIn () echter (+/- 10%). Ik verwacht dat ten minste een deel ervan wordt geïntroduceerd door de IR-zender- en ontvangermodules, maar ik heb niet voldoende apparatuur om dat te verifiëren.

Ervan uitgaande dat ik die externe fout kan verhelpen, is pulseIn () waarschijnlijk nauwkeurig genoeg zijn om dergelijke vergelijkbare pulsen te onderscheiden?

Twee antwoorden:
#1
+11
mpflaga
2014-02-21 09:38:55 UTC
view on stackexchange narkive permalink

De functie pulsein () is erg verliesgevend, omdat het een harde lus is en een getal * de veronderstelde klokcycli per lus retourneert

  ... // wacht op de puls om te stoppen terwijl ((* portInputRegister (poort) & bit) == stateMask) {if (numloops ++ == maxloops) retourneren 0; width ++;} // converteer de lezing naar microseconden. De lus is vastgesteld // 20 klokcycli lang en heeft ongeveer 16 klokken tussen de rand // en het begin van de lus. Er zal een fout worden geïntroduceerd door // de interrupt-handlers.return clockCyclesToMicroseconds (breedte * 21 + 16); 

De meest nauwkeurige methode om de timing van een pincode vast te leggen, is door de INPUT CAPTURE-FUNCTIE te gebruiken. Bekijk het dit voorbeeld. Het maakt het mogelijk om de invoer vast te leggen op 1x van de CPU voor maximale resolutie en elke rand van de invoerpin legt de klokwaarde van de timer vast voor het lezen van de gegenereerde Interrupt-service. Het maakt het ook mogelijk om de timer overflow te onderbreken om zo een grote absolute tijd vast te houden. Omdat de 1x vrij snel zal rollen. De captures slaan de tijd op in een array voor lezen door de hoofdlus.


Waar voor signalen via IR de typische bibliotheek om te gebruiken is shirriff / Arduino-IRremote bibliotheek. Waar het verschillende demo's heeft die de IR van een gedemoduleerd signaal zullen lezen en verzenden. Om iemand een schets van zijn eigen ontwerp te laten maken. Deze code creëert oorspronkelijk een timeronderbreking die de invoerpin pollt met een snelheid die wordt bepaald door

  #define USECPERTICK 50 // microseconden per klokonderbrekingstik  

in het IRremote.h-bestand. Voor mijn doeleinden heb ik het veranderd in 25 ons. Waar ik dit nog steeds vind, kunnen af ​​en toe ontbrekende pulsstromen zijn.

Merk op dat de demodulatie het beste wordt bereikt binnen de IR-ontvanger, die op zijn beurt dit interessante signaal afgeeft. Waar je wat achtergrondinformatie kunt toevoegen. Het gebruik van de typische 38KHz-modulatie komt overeen met een minimale resolutie van 26,3uS per pulscyclus. De bibliotheek van sherriff laat zien dat de meeste bauds of bits in de orde van 10+ pulsen zijn. Die lijken te voldoen aan uw gewenste timing.

microtherion / Arduino-IRremote vork van het werk van shirriff verbetert de ontvangst door de timer-interrupt-polling van de pin te vervangen door het gebruik van PinChangeInterrupts. Die ik heb samengevoegd in mijn eigen mpflaga / Arduino-IRremote -vork, die verschillende andere functies toevoegt.

Je zou dus elk van de bovenstaande bibliotheken kunnen gebruiken. Of maak je eigen app die een van de onderstaande gebruikt om randen vast te leggen.

  1. polls op een Timer-gebeurtenis (bijv. 50uS)
  2. legt de micros () vast op een PinChangeInterrupt
  3. gebruikt Input Capture Interrupts om de exacte tijd vast te stellen
Briljant antwoord. De Arduino-IRremote is een bibliotheek van zeer hoge kwaliteit. Gemakkelijk leesbaar en heeft een goed doordacht ontwerp, wat betekent dat het zeer betrouwbaar is.
#2
+2
TheDoctor
2014-02-20 20:22:36 UTC
view on stackexchange narkive permalink

Hier zijn enkele testgegevens van een pulseIn -test. De ene Arduino stuurde wat verondersteld werd 14us-pulsen te zijn, en de andere spuugde deze gegevens uit:

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,19,18,18,18 , 11,18

Zoals je kunt zien, zijn de pulsen zeker niet nauwkeurig. De tijd zou nauwkeuriger zijn als de verzendende en ontvangende einden in assemblage werden geschreven, of zelfs overgeladen aan hun eigen processors.



Deze Q&A is automatisch vertaald vanuit de Engelse taal.De originele inhoud is beschikbaar op stackexchange, waarvoor we bedanken voor de cc by-sa 3.0-licentie waaronder het wordt gedistribueerd.
Loading...