Sporadische Aussetzer beim Pin Signal Einlesen mit gpio_get () bei einem Pi Pico

  • Ich hoffe, daß mir jemand weiterhelfen kann.

    Habe einen Pico mit Arduino IDE programmiert, Programm läßt sich laden, läuft fast einwandfrei, wenn nicht diese sporadischen Aussetzer bei gpio_get ( nDACK ) passieren würden.

    Über eine Schleife sollen insgesamt 512 Bytes aus dem Pi gesendet werden. Dafür wird das nDACK Signal als Trigger verwendet.

    Nachdem das nDACK Signal auf 0 geht sollten DRQ3 und L320 ebenfalls auf 0 gehen, was im Normallfall passiert, aber eben sporadisch nicht. Und der Aussetzer ist jedesmal zeitlich woanders.

    Mit pulldown Widerstand probiert, alle irqs ausgeschaltet, Pin gewechselt, auch mit einem zweiten Pico passiert das Gleiche. Zeitlich sollte es auch kein Problem geben, für das Erkennen des Signals nDACK bis zum Setzen von DRQ3 braucht es ca. 0,3 µs, das nDACK Signal wechselt etwa alle 3 µs. Für die 512 Bytes Übertragung werden ca. 1800µs benötigt, der Fehler tritt dabei 1 x oder nicht auf. DMA und state machines sind nicht aktiviert.

    Leider kommt es immer wieder vor, daß gpio_get () nicht richtig funktioniert, und somit einen Puls auslässt, und dann natürlich nicht mehr die 512 bytes gesendet werden.

    Das Bild vom Osci zeigt die Signale 1: nDACK , 2 : DRQ3 und 3 : L320 und der fehlende pulse.

    Code
    while (i < EndSect) { // Read 512 bytes of 1 sector
      gpio_put_masked ( 0b1111111100000000000000 , (HDDTrack[i] << 14) ); // 8 bit Data output
      gpio_put ( L320 , 1 ); // Set FlipFlop for Data Register
      gpio_put ( DRQ3 , 1 ); // Set DRQ3
      i++;
      while (gpio_get ( nDACK )) ; // Wait until nDACK is set to LOW
      gpio_put ( L320 , 0 ); // Reset FlipFlop for Data Register
      gpio_put ( DRQ3 , 0 ); // Reset DRQ3
      while (!gpio_get ( nDACK )) ; // Wait until nDACK is set to HIGH
    }

    Edited 2 times, last by PeacockXT (July 20, 2023 at 9:03 PM).

  • Sporadische Aussetzer beim Pin Signal Einlesen mit gpio_get () bei einem Pi Pico? Schau mal ob du hier fündig wirst!

  • Moin PeacockXT,

    erstmal: Herzlich Willkommen im Forum!

    nDACK ist das obere Signal in deinem Bild?

    Wenn ja, dann hast du kein Problem mit gpio_get() !!

    Leider kommt es immer wieder vor, daß gpio_get () nicht richtig funktioniert, und somit einen Puls auslässt, und dann natürlich nicht mehr die 512 bytes gesendet werden.


    73 de Bernd

    Ich habe KEINE Ahnung und davon GANZ VIEL!!
    Bei einer Lösung freue ich mich über ein ":thumbup:"
    Vielleicht trifft man sich in der RPi-Plauderecke.
    Linux ist zum Lernen da, je mehr man lernt um so besser versteht man es.

    Edited once, last by Bernd666 (July 20, 2023 at 11:20 PM).

  • Das sehe ich anders. Wenn das nDACK Signal auf 0 geht, sollten die beiden anderen Signale ebenfalls auf 0 gehen. Da dies beide Signale nicht tun, muß der

    Fehler beim Einlesen des nDACK Signals sein. So sollte es aussehen.

  • Hm, also wenn das Programm in Zeile 6 die fallende Flanke erkennt, werden die beiden anderen Signale low gesetzt. Dieser Codeteil ist so kurz, dass da nicht viel schiefgehen kann.

    Da die beiden Leitungen ja im Fehlerfall korrekt auf high stehen, ist er durch die Zeilen 2-5 offenbar schon wieder durch, wenn der Fehler auftritt.

    Das legt für mich eigentlich nahe, dass das nDACK-Signal nicht immer korrekt erkannt wird. Auf dem Oszi sieht man es zwar, aber das muss ja nicht heißen, dass es am Pico auch immer erkannt wird. Wie hast du es verschaltet? Gibts irgendwelche Einflüsse durch Kapazitäten, längere Kabel vielleicht oder sowas? Wie hast du die Eingangspins konfiguriert, was Pullups/downs angeht. Möglicherweise brauchst du am Eingang keinen Pullup/Pulldown - je nach der Art des Signalausgangs arbeitet der möglicherweise sogar dagegen. Ich hab zum nDACK beim Pico nichts gefunden. Andere µC von Microchip haben am nDACk einen Pullup hängen. Wenn du auch einen Pullup am Eingang programmiert hast, hast du zwei Pullups, was vielleicht Probleme machen könnte.

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

  • Das Signal vom nDACK sollte soweit sauber sein, jedenfalls wenn man nach dem Osci geht. Ansonsten wird das Signal von einem ATF1504 mit 3,3 V erzeugt, und geht dann direkt in den Pico. Einzig eine LED über 1000 Ohm Widerstand , mit ca. 1,5 mA wird noch vom Pin versorgt.

    Bin am überlegen, wie die Flankensteuerung ( ausser mit IRQ ) noch anders realisiert werden kann.

    Pulldown und Pullup Widerstände extern und intern, alles probiert. Ich habe nochmal ein paar neue Picos bestellt, mal sehen , was die machen.

  • Entnimmst du die 1,5 mA für die LED aus der Signalspannung? Die leuchtet dann, wenn das nDACK Signal high ist? Für wie viel mA sind die Ausgänge dieses ATF1504 ausgelegt?

    Wo hast du das Signal mit dem Oszi abgenommen? Direkt am GPIO? Auf deinem Oszi-Bild sind leider keine Spannungen zu sehen. Wo liegen die denn?

    Und wie ist das alles genau verschaltet?

    Also, das ist alles recht spekulativ, so lange du uns die genaue Schaltung und Programmierung des Ausgangs und des Eingangs (Pullup/Pulldown, Push-Pull, Open Drain, ...) nicht sagst. Klar ist eigentlich nur eins - da stimme ich dir zu - der Pico bekommt das Signal nicht. Ein Laufzeitproblem schließe ich genauso aus wie du. Also sind entweder alle Picos defekt (wenigstens deine beiden) oder dein Signal ist nicht korrekt oder es kommt jedenfalls nicht korrekt an.

    Hast du mal die LED weggelassen, den Pullup/down beim Pico abgeschaltet und ein sehr kurzes Kabel verwendet? Ich würde den Fehler irgendwo dort vermuten. Dein Programm sehen wir auch nur ausschittsweise - da könnte irgendwo anders noch ein Haken sein.

    Jedenfalls ist es nicht zielführend, darauf zu beharren, dass alles in Ordnung ist, denn das ist es ja offensichtlich eben nicht. (Es sei denn, beide Picos sind defekt.)

    Bin am überlegen, wie die Flankensteuerung ( ausser mit IRQ ) noch anders realisiert werden kann.

    Wie wäre es alternativ, wenn du direkt den Eingangswert nDACK auf die Ausgänge schreibst? Dann kannst du zumindest sehen, ob es unter anderen Umständen vielleicht fehlerfrei läuft. Ungefähr so:

    Code
    while(true) {
        gpio_put ( L320 , gpio_get ( nDACK ) );
    }

    Die eigentliche Funktion deines Programms fehlt dann, aber das müsste rein zum Testen dein nDACK-Signal narrensicher auf den einen Ausgang schalten.

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

    Edited once, last by Gnom (July 21, 2023 at 6:48 PM).

  • Das Osci nimmt die Signale direkt am Pico ab, Signalspannung somit 3,3 V, am Osci sind 5V DC Spannung eingestellt. Der ATF kann noch einiges an Strom mehr vertragen. Auch schon probiert, wenn die 3.3V Versorgung vom Pico kommt, und ohne Diode, löst das Problem auch nicht.

    Ich habe mal die Schaltung grob skizziert.

    Ich habe nochmal getestet, in ca. 2 von 3 Fällen kommt genau 1 Fehler in 1,8ms, 2 Fehler habe ich noch nicht gesehen. Das entspricht einer Frequenz von

    1 / 1,8ms = 555 Hz max. Gibt es irgendetwas im Pico, was mit dieser Frequenz oder etwas weniger arbeitet ?

    Ich habe das Gefühl, daß hier ergendetwas im Pico die gpio_get () Abfrage verzögert. IRQ und DMA kann ich ausschliessen, und state machine hab ich nicht programmiert.

    Wie wäre es alternativ, wenn du direkt den Eingangswert nDACK auf die Ausgänge schreibst? Dann kannst du zumindest sehen, ob es unter anderen Umständen vielleicht fehlerfrei läuft. Ungefähr so:

    Code
    while(true) {
        gpio_put ( L320 , gpio_get ( nDACK ) );
    }

    Die eigentliche Funktion deines Programms fehlt dann, aber das müsste rein zum Testen dein nDACK-Signal narrensicher auf den einen Ausgang schalten.

    Gute Idee, muß mir aber nochmal Gedanken machen, wie ich das mit der Flankenabfrage hinkriege.

    Bin fast entschlossen einen Testaufbau mit 2 picos zu machen. Einer generiert das Signal, der 2. zählt die Flanken. Noch gebe ich nicht auf.

  • Du brauchst für diesen Test ja keine weitere Flankenabfrage. Es geht ja hier erst mal nur drum, ob das Signal vom Pi erkannt und durchgegeben wird.

    Was passiert, wenn du mehr als 512 Signale verarbeitest - kommt der Fehler dann periodisch?

    Hast du irgendwelche Libraries im Einsatz oder Interrupts oder irgendwas? Was macht der restliche Code? Lass doch mal nur die Signalerkennung laufen und schmeiß alles andere raus, vor allem alle Libs, die du nicht brauchst.

    Hast du schon mal einen anderen Pin probiert?

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

  • Jatzt wird es richtig gruselig.

    Mit einem ESP32 habe ich versucht das nDACK Signal mit Endlosschleife nachzubilden, und dann dem Pico zur Verfügung zu stellen.

    Ergebnis: ohne das ich den Pico angeschlossen hatte, gibt es Signalaussetzer bei dem ESP32 exakt alle 1,000 ms !

    Der ESP32 wird von einem anderen Netzteil versorgt, die 5V sind stabil. Im Moment bleibt als Fehlerquelle einzig das Osci über.

  • Hast du zufällig nen 555 rumliegen, um das nochmal mit einem Signal zu testen, bei dem kein µC was vermurksen kann? Oder einen µC, der wirklich deterministisch ist (Arduino oder sowas), also ohne irgendwelche Firmware und sowas. Ich trau dem Zeug nicht - weder dem ESP32 mit seinem RTOS noch dem Pi Pico.

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

  • Ich konnte es nicht glauben, aber beim ATMEGA2560 genau dasselbe Problem, ca. alle 1 ms ein verlängertes Signal, mal positiv, mal negativ.


    Programmcode aufs Wesentliche beschränkt. Erst als ich definitiv noInterrupts () im Setup ergänzt hatte, war der Fehler weg.

    War schon drauf und dran einen neuen OSCI zu bestellen.

    Die Arduino IDE haut da irgendetwas rein.

  • Du darfst kein digitalWrite nehmen. Das ist zu langsam und verschluckt sich gerne mal. Du musst die Register direkt ansprechen.Selbiges gilt für ESP32 etc...

    Du solltest ein TimerInterrupt einbauen, welcher all x-Sec eine Flag umschaltet, anschließend schreibst du das Register der GPIOs.

    Wenn's brennt 112 hilft weiter!

  • Offenbar nutzt die millis()-Funktion einen Timer Interrupt des µC.

    Siehe hier und hier.

    Du müsstest also die Interrupts ganz abschalten oder zumindest den Timer stoppen, der genutzt wird.

    Vielleicht kann man auch den Interrupt löschen.

    Das ist ja echt etwas krass! Ich hätte erwartet, dass millis() auf einen Hardwarezähler zugreift.

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

  • Das delaymicroseconds() braucht ja auch keinen Counter, der im Hintergrund permanent läuft. Die Funktion zählt ja nur Prozessortakte.

    Aber hier gings ja nur um das Finden der Ursache. In deinem ursprünglichen Programm hast du ja gar keine delays - insofern spielt das eh keine Rolle. Jedenfalls, wenn du die Interrupts abschaltest, müsste dein Programm fehlerfrei laufen. Hast du es schon probiert?

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

  • Es war definitiv ein Interrupt, der beim Pico gestört hat. Habe alle Interrupts ausgeblendet, und siehe da, keine Lesefehler mehr. Ich denke, das hat auch was mit den libraries zu tun.

    Na jedenfalls komm ich jetzt weiter.

    Gnom : Vielen Dank für die Unterstützung.

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!