Wie einen präzisen Einzelpuls an einem Portpin realisieren?

Hallo zusammen,
für eine kleine Anwendung brauche ich mal einen guten Vorschlag um folgendes zu realisieren:
Ausgabe einen Einzelpulses mit präzisen 7850us. Diese Zahl ist ein Beispiel und soll nur aufzeigen, daß es hier wohl an die Auflösungsgrenze geht, was die Genauigkeit betrifft.
Feinabstimmung mit iterativ angepassten Zählerwerten ist möglich. Mit 16MHz Takt müsste das machbar sein.
Habt ihr gute Vorschläge oder gar fast fertige Lösungen parat?
Vielen Dank! :slight_smile:

Hi

Nicht ganz unwichtig dabei: Muß der Arduino noch was Anderes machen, als diesen Impuls?
Also WÄHREND des Impuls.
Nein: delayMicroseconds()

MfG

Inline Assembler und/oder direkte Portoperationen oder CombiePin könnte Dir helfen.

postmaster-ino:
Hi

Nicht ganz unwichtig dabei: Muß der Arduino noch was Anderes machen, als diesen Impuls?
Also WÄHREND des Impuls.
Nein: delayMicroseconds()

MfG

Geht nicht: 7850 ist nicht ohne Rest durch 4 teilbar.

Gruß Tommy

kaleidoskop:
Ausgabe einen Einzelpulses mit präzisen 7850us. Diese Zahl ist ein Beispiel und soll nur aufzeigen, daß es hier wohl an die Auflösungsgrenze geht, was die Genauigkeit betrifft.

Auflösung und Genauigkeit sind aber 2 verschiedene Paar Stiefel. Da musst Du schon genauer sagen um was es dir geht. Wie Tommy schon anmerkte, hat delayMicroseconds auf den 'Standard' Arduinos eine Auflösung von 4µs. Das hat aber wenig mit der Genauigkeit zu tun, die hängt von anderen Faktoren ab - z.B. Resonator oder Quarz als Taktgeber. Wenn man direkt die Timer nutzt, kann man die Auflösung wesentlich höher treiben - die Genauigkeit wird aber nicht prinzipiell besser.

Also Butter bei die Fische: Was willst Du machen und was brauchst Du wirklich?

Ok, vielen Dank soweit!
Und, Fehler von mir bei der Anforderung: kürzester Puls 6us, längster Puls 20us.
Mit einer Toleranz bzw. Schrittweite von +/-0,5 us kann ich leben. Während der Singlepulsausgabe kann alles andere problemlos warten. Bei 16MHz habe ich eine Taktdauer von 0,0625us und damit bei 6us 96 Prozessortakte zur Verfügung…
Ja, womöglich muss ich das mit einem externen Counter realisieren, das gefällt mir aber gerade nicht!

Zu Butter bei die Fische: Die Anforderung ist im Grunde einfach, aber wegen der sehr kurzen Zeiten nicht trivial! Auf Tastendruck soll ein kurzer, aber bezüglich der Pulsdauer präziser Puls abgegeben werden. Die Zeit zwischen Tastendruck (Trigger) und Puls ist nahezu beliebig. Jedoch ist die genaue Pulslänge noch unbestimmt!

Messmethode hinterher ist ein Oszilloskope bzw. ein Frequenzzähler.

Viele Grüße und bleibt gesund

Hi

Eine Lösung in Inline-Assembler könnte mir gefallen - denke aber, daß wir hier mit einem Timer ebenso ans Ziel kommen.
Wobei 0,5µs nur 8 Takte sind - Das ist nicht viel Holz, allerdings sollte sich der Overhead bei beiden Aufrufen in gleicher Größe abspielen.
Vorstellung:
Startwert OCRA und Endwert OCRB berechnen, Timer starten, fertig.
ISR OCRA startet den Impuls
ISR OCRB beendet den Impuls und stoppt den Timer

Da zwischen Start und Stop mindestens 6µs liegen (96 Takte), sollten wir in der Zeit den Ausgang sicher gesetzt und die ISR verlassen haben - denke, hier brauchen wir direkte Port-Manipulation, da digitalWrite zu langsam sein dürfte.
(meine Combie hatte dazu Mal was getestet)

MfG

Hallo,

einen Timer programmieren der sich mit Tastendruck starten lässt und mit Pulsende automatisch stoppt. Dann haste volle Kontrolle über die Pulslänge und Genauigkeit sowieso. Dazu bedarf es noch einer Tasterentprellung die nur auf erneutes drücken reagiert.

kaleidoskop:
Messmethode hinterher ist ein Oszilloskope bzw. ein Frequenzzähler.

Was spricht dagegen, es bei/nach dem Messen anzupassen?

Gruß

Gregor

Gerade habe ich das hier gefunden...

Ich hoffe, damit komme ich als „Newbe“ irgendwie klar... (Bin eher Hardwarelastig aufgestellt)

Gegen eine Anpassung nach einer Messreihe spricht nichts!

kaleidoskop:
Ja, womöglich muss ich das mit einem externen Counter realisieren, das gefällt mir aber gerade nicht!

Wieso externer Counter? Die internen Timer sind perfekt dafür geeignet. Im Grunde wurde ja schon geschrieben, wie es gehen kann.
DigitalWrite braucht aber ca. 5µs - da müsste man in der Tat mit direkter Portmanipulation arbeiten. Das sollte aber auch so hinzubekommen sein, dass der Output-Pin nur direkt vom Timer gesteuert wird. Da gibts dann dieses Problem nicht.

Edit: in dem oben angegebenen Link dürfte das genau so realisiert sein.

Einfache Lösungen mit vielen Abkürzungen sind oft deutlich komplizierter als Datenblatt lesen ...

Der oben angegebene Link ist super! Die Pulse sind im 62,5ns-Raster aufzulösen. Das bedeutet, dass so die maximal höchste Auflösung, also die Quarzfrequenz erreicht wird. Meine Anforderung ist mehr als locker damit umsetzbar! It‘s really like magic!

Achtung:
Auflösung und Genauigkeit sind 2 verschiedene Größen.
Die Auflösung ist in der Größe der Taktfrequenz.
Die Genauigkeit hängt auch von der Taktfrequenz ab. Diese ist bei einem Arduino mit Resonator wie der UNO oder MEGA 2560 nur 0,5% genau.
Ein Quarz ist um den Faktor 100 genauer zB bei einem Leonardo bzw MICRO.
Grüße Uwe

Kann mir bitte noch mal jemand auf die Sprünge helfen?
Ich habe den SingleShotPuls nach der hier http://wp.josh.com/2015/03/05/the-perfect-pulse-some-tricks-for-generating-precise-one-shots-on-avr8/ beschriebenen Art und Weise generiert. Das klappt perfekt. Nun brauche ich das Signal invertiert. Wie mach ich das am besten?
Lieben Dank und bleibt gesund!

Lass doch mal "| _BV(COM2B0)" weg....

ohne Gewähr

@combie
Super! Vielen lieben Dank dir! Funzt einwandfrei!
Das erleichtert mir die Schaltung dahinter!
Bleib gesund! Euch allen eine gute Zeit!

:sunglasses: