Ich will mit dem PiPico2 Frequenzen zählen. Das Ganze soll über die
Periodendauermessung funktionieren, da ich eine möglichst schnelles
Update der aktuellen Frequenz benötige.
Mein Testaufbau ist ein Frequenzgenerator mit 100kHz Rechteck an den
Pin16 des PiPico geführt. So wie es aussieht, entstehen hier Fehler bis
zu ca. 20%.
Kannst du den Fehler besser beschreiben? Ist für mich nicht klar ob du
einen jitter hast oder nur falsche Anzeige. Kenne den Pico nicht, aber
brauchst du unbedingt Variable-Typen inkl. double und print?
Christoph M. schrieb:> Ich will mit dem PiPico2 Frequenzen zählen. Das Ganze soll über die> Periodendauermessung funktionieren, da ich eine möglichst schnelles> Update der aktuellen Frequenz benötige.
Wenn es sowohl schnell, als auch genau und ohne CPU Belastung gehen
soll, dann empfehle ich nachdrücklich den Schwenk auf die PIO.
Der Pico2 läuft (default) mit 150MHz,
dh. damit ist eine Auflösung von 6 2/3ns möglich.
Wer glatte Zahlen mag, bei 200MHz──▶5ns.
Michael P. schrieb:> Kenne den Pico nicht, aber> brauchst du unbedingt Variable-Typen inkl. double und print?
Der Pico2 hat zwei FPUs, bei float Addition und Multiplikation innerhalb
eines Taktzyklus, Division innerhalb max. acht (IIRC)
Double braucht mit dem CoPro etwas länger, was aber an der Stelle völlig
egal ist.
Ich könnte mir vorstellen, dass der ganze multiple Arduiono
Überbau/Abstraktion einer präzisen Messung nicht unbedingt zuträglich
ist.
Michael P. (mipo)
08.10.2025 07:12
>Kannst du den Fehler besser beschreiben?
Die Anzeige funktioniert ziemlich sicher. Das Diagramm zeigt eher
Ausreißer als Jitter. Klar, dass es so was bisweilen gibt. Manchmal auch
durch Übertragungsfehlern. Der Screenshot ist vom Plotter der
Arduino-IDE und das funktioniert stabil.
Die Ausreißer würde ich eher als Interrupt-Querschläger ansehen. Ich
hätte da weniger erwartet, weil ich die Zeitmessung mit "setup1" ja auf
den zweiten Kern des PiPico gelegt habe.
Norbert (der_norbert)
>Wenn es sowohl schnell, als auch genau und ohne CPU Belastung gehen>soll, dann empfehle ich nachdrücklich den Schwenk auf die PIO.
Da wäre die Frage, ob es überhaupt mit der hohen Auflösung geht. Auch
die PIO muss ja ein paar paar Instruktionen durchführen.
Vor allen Dingen scheint mir der Aufwand recht hoch:
Laut
https://github.com/earlephilhower/arduino-pico/discussions/221
soll man den Online-PIO Assembler
https://wokwi.com/tools/pioasm
verwenden.
Christoph M. schrieb:> Da wäre die Frage, ob es überhaupt mit der hohen Auflösung geht. Auch> die PIO muss ja ein paar paar Instruktionen durchführen.
Zur ersten Frage: Ja, geht es.
Die PIO arbeitet jede Instruktion innerhalb eines Taktzyklus ab.
Zählen braucht eine, springen braucht eine. (Wenn man's sauber macht)
Da man aber zwölf Statemachines zur Verfügung hat, kann man getrost zwei
davon zeitversetzt das gleiche messen lassen.
Ich selbst habe ganz sicher schon tausende Zeilen PIO-Assembler
geschrieben (nicht übertrieben) und nicht einmal auf einen
Online-Gehgips zurück greifen müssen. Zwei Hände voll Instruktionen
stellen jetzt lernmäßig nicht die Eiger Nordwand in den Schatten (Sorry
für's Wortspiel)
Christoph M. schrieb:> So wie es aussieht, entstehen hier Fehler bis zu ca. 20%.
Das wundert nicht, da ohne richtige Synchronisierung von Eingangssignal
und Referenztakt keine stabile Messungen möglich sind. Entweder
verwendest Du externe D-FFs oder eine interne PIO + DMA.
Intern habe ich eine Lösung für den RP2040 auch für Arduino-IDE, die
aber beim PicoPi2 wegen vermutlich wieder veränderter Arduino-Version
nicht richtig compiliert wird. Beispiele kannst Du hier in der
Codesammlung finden.
Läuft die serielle Kommunikation über USB? Dann unterbrechen oder
blockieren die USB-Interrupts sporadisch deinen GPIO-Interrupt, was dann
zu ungenauen Zeitmessungen führt.
Lässt du die Ausgabe der Ergebnisse über einen UART laufen, sollte das
nicht passieren.
Yalu X. (yalu) (Moderator)
08.10.2025 09:38
>Läuft die serielle Kommunikation über USB? Dann unterbrechen oder>blockieren die USB-Interrupts sporadisch deinen GPIO-Interrupt, was dann>zu ungenauen Zeitmessungen führt.
Ich habe das Programm noch mal umgeschrieben und Interrupt-frei gemacht.
Es sind dann keine Ausreißer mehr sichtbar. Das Ganze läuft extra ohne
alles auf dem zweiten Kern. Aber die maximale Abweichung liegt immer
noch einiges über der anvisierten Nanosekundenauflösung (siehe Anhang,
y-Achse: us).
>Intern habe ich eine Lösung für den RP2040 auch für Arduino-IDE, die>aber beim PicoPi2 wegen vermutlich wieder veränderter Arduino-Version>nicht richtig compiliert wird.
Ich verwende das Early-Hill-Power Framework, das sollte recht stabil
sein und besser als das originale Arduino PiPico mit MBed:
https://github.com/earlephilhower/arduino-pico
Dort kann man auch die nativen SDK-Funktionen benutzen (siehe oben im
Code "gpio_get" statt digitalRead).
Wo genau kann ich deinen RP2040 Code finden?
Christoph M. schrieb:> Wo genau kann ich deinen RP2040 Code finden?
Hier findest Du die Entwicklungsgeschichte zu meinen RP2040 Schaltungen:
http://mino-elektronik.de/fmeter/fm_software.htm#bsp_RP2040
Bei der 'Luxusversion' mit TDC gibt es die Ausführungen für IAR-EWARM,
Segger-IDE und Arduino, die nahezu identisch sind. Die Messungen laufen
alle über Interrupts im Hintergrund. Das bedingt wegen der standardmäßig
bei Arduino vorhandenen USB-Schnittstelle auf der einen Seite, daß die
Interruptvektoren ins RAM gelegt werden müssen. Auf der anderen Seite
muß die 'RP2040.h' der beiden anderen IDEs für Arduino passen und darf
nicht mit den dortigen *.h-Dateien kollidieren.
Für Arduino funktionierte das mit IDE V 2.3.2 package "Raspberry Pi Pico
3.7.0". Bei neueren Versionen sind unverständlicherweise die *.h-Dateien
geändert/getauscht worden. Mir war es dann zu blöd, diesen Änderungen
hinterher zu programmieren.
Im Anhang findest Du meine unvollendete Version, die eigentlich noch um
serielle Befehle und Speicherung von Konstanten im FLASH-Speicher
ergänzt werden sollte. Zur Datenübertragung wird USB benutzt.
DEF_F1_MESSZEIT (in ms) kannst Du ja auf den benötigten Wert
verkleinern.
Ich hoffe, daß die Kommentare schon zur Verion passen.
Christoph M. schrieb:> Ich habe das Programm noch mal umgeschrieben und Interrupt-frei gemacht.> Es sind dann keine Ausreißer mehr sichtbar.
Sehr gut, dann lag es also tatsächlich an den Interrupts.
> Aber die maximale Abweichung liegt immer noch einiges über der> anvisierten Nanosekundenauflösung
Mit welche Taktfrequenz läuft der Pico2? Glaubst du wirklich, man könne
damit 1ns auflösen?
> (siehe Anhang, y-Achse: us).
Ich habe mal mit großer Anstrengung versucht, die Schwankungsbreite aus
deinem maximal schlecht skalierten Diagramm herauszulesen und komme auf
etwa ±46ns. Das ist besser als ich von einer Lösung mit Arduino ohne PIO
erwartet hätte.
Besser geht es natürlich mit PIOs.
Yalu X. schrieb:> Mit welche Taktfrequenz läuft der Pico2?
150MHz ist Standard.
> Glaubst du wirklich, man könne damit 1ns auflösen?
Nein, das würde 1GHz erfordern.
Bei 200MHz kann man aber schon präzise 5ns auflösen.
Norbert (der_norbert)
08.10.2025 11:35
>Pro Schritt 100 Messungen, von 1997cycles … 2003cycles.>Bei 200MHz: 100150.230 Hz … 99850.230 Hz
Sind das Messungen? Wenn ja, dann sind sie verdächtig: 1 Bit
Quantisierungsfehler sollte immer drinn sein.
Christoph M. schrieb:> Sind das Messungen? Wenn ja, dann sind sie verdächtig: 1 Bit> Quantisierungsfehler sollte immer drinn sein.
Das sind Messungen. Aber auf einem Controller.
PIO1 erzeugt die Frequenz auf GPIO16, PIO0 misst sie auf GPIO17.
Da muss man nicht so eine große Brücke bauen! ;-)
Also 100% synchron.
Aber du hast recht, wenn man etwas Externes messen würde, dann käme 1
cycle Unschärfe hinzu. (Plus die ppms der beteiligten Quarze)