AD Wandler auslesen / Interrupt

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo!

    Ich muß/will/darf ein Problem lösen, bei dem ich doch erst mal nachfrage, da ich mir nicht sicher bin, ob das überhaupt möglich ist.

    Es geht um das auslesen eines AD-Wandlers über die SPI Schittstelle. Genauer geht es um den ADS8861.

    Dieser schafft max 1 MS/s - mir würden aber auch schon 500 kS/s reichen. Nun habe ich gelesen, daß die SPI Schnittstelle nur mit 16 (oder 32) MHz taktbar ist. Mehr soll zwar einstellbar sein, aber nicht mehr funktionieren.

    Der ADS8861 kann mit einem SCL bis 15ns pro Takt betrieben werden -> das wären 66 MHz. Bei 500 kS/s und 16 Bit würden 1,7µs für die 16 Takte bleiben (ca 300ns werden für die Wandlung benötigt). Das sind etwa 10Mhz (1,7µs / 16 Takte). Das sollte also mit den 16MHz möglich sein.

    Das Problem ist jetzt: Der AD Wandler braucht etwa 300ns zum Wandeln. Es gibt eine Funktion, bei der das Wandlungsende über einen Pulldown der SDA Leitung signalisiert wird.

    Lt. Application Note kann man dies über einen Interrupt auslösen lassen, nur sind die Lösungen (die ich bis jetzt gesehen habe) alle nicht hardwarenahe. Siehe: Sensor-Signal per Interrupt abfragen

    Um einen echten Hardware(Kernel)Interrupt zu erzeugen, muß man wohl den Kernel neu komplilieren.

    Die Frage ist nun: Hat das schon mal jemand gemacht und kann mir sagen, wie schnell der Interrupt dann ist?
    Naiv würde ich sagen: 700Mhz Taktfrequenz - dann sollte der Interrupt innerhalb von 5 Takten ausgelöst sein - also deutlich unterhalb 10ns.

    Oder ist die Interruptlösung nichts, und es ist besser zu pollen/warten und dann auslesen und auf gute Datenraten hoffen?


  • ....habe ich gelesen, daß die SPI Schnittstelle nur mit 16 (oder 32) MHz taktbar ist. Mehr soll zwar einstellbar sein, aber nicht mehr funktionieren.

    die Angaben die ich gelesen hatte waren widersprüchlich, von etlichen 10-20 MHz bis 2MHz
    kann aber nix zu sagen - User -ds- dreamshader weiss evtl. mehr

    ...Es gibt eine Funktion, bei der das Wandlungsende über einen Pulldown der SDA Leitung signalisiert wird.

    SDA am SPI ? verstehe ich nicht, SDA ist I2C, SPI ist was anderes.....

    Lt. Application Note kann man dies über einen Interrupt auslösen lassen, nur sind die Lösungen (die ich bis jetzt gesehen habe) alle nicht hardwarenahe. Siehe: Sensor-Signal per Interrupt abfragen

    Um einen echten Hardware(Kernel)Interrupt zu erzeugen, muß man wohl den Kernel neu komplilieren.

    nö dafür gibt es LIBs, wiringPI, PGIO - User -ds- dreamshader

    wobei pollen schneller sein soll als Interrupt weil das Interrupthandling wegfällt und er beim schnellen pollen kaum Systemlast verursacht ! (so habe ich das im Hinterkopf)

    Die Frage ist nun: Hat das schon mal jemand gemacht und kann mir sagen, wie schnell der Interrupt dann ist?

    - User -ds- dreamshader weiss mehr

    suche mal seine Themen und Beiträge oder frage direkt.

    lasst die PIs & ESPs am Leben !
    Energiesparen:
    Das Gehirn kann in Standby gehen. Abschalten spart aber noch mehr Energie, was immer mehr nutzen. Dieter Nuhr
    (ich kann leider nicht schneller fahren, vor mir fährt ein GTi)

    Einmal editiert, zuletzt von jar (10. Juni 2014 um 13:43)

  • jar, jar ... äh ... ja, ja ... immer auf die Kleinen ....

    Also zum Thema Timing-Zeiten kann ich so ad hoc nix sagen.
    Ich realisiere so was generell über ISR, weil das wohl das resourcen-schonendste Vorgehen ist.

    Ich verwende abei pigpio, die sich wohl den DMA-Takt zunutze macht.
    Auf der Entwickler-Site ist sicher mehr an Info zu finden, falls nicht, bin ich sicher, dass der Autor gerne weiterhilft.

    Von der wiringPi würde ich eher Abstand nehmen ... die ist imho bei weitem nicht schnell genug.

    Alternativ gibt es noch die bcm2835 von Mike McCauley.
    Die habe ich aber vor längerer Zeit mal aus meinem Sortiment genommen, weil sie mir bei der einen oder anderen wheezy-Version den einen oder anderen bösen Streich gespielt hat.

    Als Betriebssystem verwende ich derzeit ausschliesslich Raspbian wheezy.

    Das Problem bei zeitkritischen Anwendungen ist, dass wheezy ja kein RTOS ist, und aufgrund der timeslices durchaus mal zu Verzögerungen kommen kann, die sich imho auch nicht verhindern lassen.
    Das fällt im Normalbetrieb nicht auf, kann aber gerade bei solchen Dingen ein k.o. Kriterium sein.

    Die Kernel-Crew von wheezy scheint allerdings daran zu arbeiten, in etwa an ein RTOS heranzukommen. Eine fundierte Aussage dazu kann ich aber leider nicht machen, ich schliesse das lediglich aus den Kernelsourcen.

    Andere Entwickler setzen z.B. auf ARCH.
    Ob hier ein anderes OS ein besseres Verhalten hat, kann ich nicht sagen.
    Ich weiss nur von z.B. mmi, dass er ARCH auf dem RPi fährt.
    Möglicherweise gibt es noch andere Softies hier, die ARCH verwenden.
    mmi wäre afaik auch jemand, der noch was zur bcm2835 sagen kann.

    Fehlt noch was?

    cu,
    -ds-

  • Hallo miteinander,

    eigentlich wurde ja schon alles gesagt - mehr weiß ich dazu auf die Schnelle auch nicht.

    Zitat von jar


    wobei pollen schneller sein soll als Interrupt weil das Interrupthandling wegfällt und er beim schnellen pollen kaum Systemlast verursacht !


    Also grundsätzlich stimmt das natürlich nicht, dafür sind Interrupts ja da - schnelles Pollen frisst unnötigerweise die CPU-Zeit, da kann ich mich DS nur anschliessen:


    Ich realisiere so was generell über ISR, weil das wohl das resourcen-schonendste Vorgehen ist.

    Der Broadcom SoC im RPi scheint bezüglich HW-Interrupts aber recht mager ausgelegt zu sein - vermute ich zumindest, sonst hätte man bei "wiringPi", "pigpio", etc. sich was anderes einfallen lassen.
    Bei "pigpio" ist aufgrund der Nutzung des DMA-Takts eine hohe Genauigkeit zu erwarten, bei "wiringPi" läuft es über zeitlich gesteuerte Softwareinterrupts des Kernels. Der Standardkernel ist nicht realtimefähig (wie oben schon angesprochen), da kann man die Genauigkeit bei höheren Frequenzen vergessen, sofern sie überhaupt noch realisierbar sind. "pigpio" ist deshalb aus meiner Sicht die beste Lösung.
    Eventabhängige Interrupts (wie beispielsweise bei einem Microcontroller) gibt es bim RPi also scheinbar nicht - leider! :(


    Ich weiss nur von z.B. mmi, dass er ARCH auf dem RPi fährt.


    Bei mir läuft überall Archlinux, weil mir "TheDebianWay" nach vielen Jahren mit Debian SID nicht mehr gefallen hat. Ich bevorzuge möglichst "unverfälschte" Originalpakete direkt vom jeweiligen Entwickler sowie brandneue Softwareversionen. Desweiteren sind viele Debian scripts aus meiner Sicht unnötigerweise verkompliziert und "wheezy" wäre mir viel zu altbacken. Warum soll man sich mit bugs herumschlagen, die möglicherweise längst keine mehr sind? Und es gäbe noch einige Gründe - aber soweit erstmal genug OT. ;)

    Für den Einsteiger ist auf jeden Fall Raspbian zu empfehlen, weil man auf eine riesige community zurückgreifen kann und die Erstinstallation wesentlich besser vorbereitet ist.


    mmi wäre afaik auch jemand, der noch was zur bcm2835 sagen kann.


    Wie kommst Du darauf - die habe ich noch nie verwendet - wahrscheinlich meintest Du "pigpio" - s.o.

    Gruß, mmi

  • Ja hey mmi,


    ...
    Wie kommst Du darauf - die habe ich noch nie verwendet - wahrscheinlich meintest Du "pigpio" - s.o.
    ...

    hm ... da hast Du wohl recht. Das war nämlich orb, der diese bcm Lib verwendet hat.
    Tja ... UV-A, UV-B, > 30° ... da kommt der Eintopf in der Birne schon mal durcheinander ;) ...

    cu,
    -ds-

  • Hey,

    erst mal vielen Dank für die Antworten!

    Ich habe gestern mal den ADC el. angeschlossen (super Sache 10 Kabel an ein SMD Bauelement mit 0,5er Pitch anzulöten - egal - ist ja nur zum testen)

    Folgende Beobachtungen habe ich gemacht:

    Ich habe die Bibliotek von Mike McCauley (bcm2835) ausprobiert.

    Ein Takt von mehr als 16MHz ist unvernünftig. Bei allem, was höher ist, kann man nicht mehr von Digitalpegeln sprechen. Das wird dann so eine Art halbherziger Sägezahn und Glücksrad, ob der ADC die Takte noch als solche erkennt.

    Das größere Problem sind die Kaffeepausen. Nimmt man die Lib, so wie sie ist, kommt man auf sagenhafte 43kS/s. Ob man nun 4 oder 16MHz SPI Takt nimmt ist relativ egal. Das macht mein 10000 Werten 3...4ms aus. Nerviger sind die Pausen, welche die Lib macht.

    Ich habe mir mal den Teil der SPI in mein Testprogramm geholt und die Sache etwas "getweakt". Ohne Garantie, daß die Werte korrekt sind, kommt man da schon mal auf 350kS/s. (Habe nur den Oszi im Blick gehabt). Vermutlich werde ich nur die Lottozahlen gelesen haben - die 10µS "Wait" in der Lib werden schon ihren Grund haben.

    Alles in allem "hmm" - ich überlege schon, ob ich das über normale Port-Operationen nicht schneller hinbekomme. Damit würde man zumindest die Wartezeiten der SPI (die vermutlich Softwaremäßig drinn sein müssen) umgehen. Mit etwas Mühe bekommt man da sicher 15..20MHz Takt hin.

    Hat jemand einen (verständlichen) Link zur SPI des BCM2835, wie ich die selbst Hardwarenahe Programmieren kann? Das dumme an der Lib von Mike McCauley ist, daß man da immer erst mal etwas schreiben muß, bevor man lesen kann - jedenfalls bei den Standardfunktionen. Ich muß eigentlich nur ein Wort lesen - so schnell wie möglich ;)

  • Tjaa ... das ist wohl so, mit der SPI Lib ... erst schreiben, dann lesen.
    Keine Ahnung warum ... aber das ist scheinbar irgendwo so definiert :s

    Ob das mit der pigpio besser ist, sei mal dahingestellt ...

    Mit einem Link kann ich leider nicht dienen, aber über eLinux könntest Du da fündig werden.
    Wäre im Übrigen nicht der Einsatz eines Arduino da besser?
    So einen Pro Mini bekommst Du schon für unter 3,- € ... und der hat ne Menge I/Os und 16 MHz ...

    cu,
    -ds-

  • Mit einem Link kann ich leider nicht dienen, aber über eLinux könntest Du da fündig werden.
    Wäre im Übrigen nicht der Einsatz eines Arduino da besser?
    So einen Pro Mini bekommst Du schon für unter 3,- € ... und der hat ne Menge I/Os und 16 MHz ...

    cu,
    -ds-

    Ich hab auch mal gelesen, daß manche sowas über ein Risc OS lösen ... wobei ich sicher nicht so Hardcore bin ;)

    In einen Arduino müsste ich mich von Null aus einarbeiten - dafür ist der Termin zu eng.

    Mal schauen - die Frequenzen der GPIO sind ja eher ein aufgeregter Gleichstrom - Es wäre auch ein Workaround möglich, indem ich einfach dauerhaft auslese und die Impulse für den Wandler über einen Binärzähler erzeuge. Dann müsste man halt den Datenstrom später auseinanderfrickeln.

    Dauerhaft brauche ich die 500kS/s nicht. Sagen wir mal 5000 Samples und dann ist Zeit zum rechnen. Ich muß das nur erst mal mit der Geschwindigkeit in den Speicher des Raspberry bekommen...

  • Na ich will Dir da nix einreden, aber das Arduino Projekt ist wirklich klasse, die Hardware günstig bis spottbillig die IDE watschneinfach und es gibt praktisch für alles ein Beispiel.
    Ist ja vielleicht mal was für den "Gedanken-Stack" ;) ...

    Ach wird schon,
    ich wünsch Dir was und wenn wir was helfen können (ausser dummes Zeug zu reden) ... gerne ;) ...

    cu,
    -ds-

  • Hach - das Forum gefällt mir - ihr seit locker :)

    Selbst mit einem N00b, der noch nie was mit Raspberry und SPI gemacht hat.

    Naja - hardwarenah kann ich ganz gut programmieren, ich muß mal genauer in die Doku zur CPU schauen. So wahnsinnig ist das ja nicht, was ich machen will..

  • So .. Neuigkeiten:

    Ich hab die Lib auseinandergenommen und auf "mein" Problem optimiert (ich will ja nix schreiben, sondern nur lesen). Dazu kommt (Asche auf mein Haupt), daß der ADC sich doch mit dem Teiler 4 (62MHz SPI Takt) auslesen läßt. Als ich verwundert auf meinen Oszi geschaut habe, hab ich dann auch gesehen warum. Man sollte halt keinen 62MHz Takt mit einem 100MHz Oszi anschauen ...

    Resultat: 1 Mio mal wandeln dauert nun 1892ms (das macht 528 kS/s) - Perfekt. Die Daten schauen soweit konsistent aus. Bei Kurzschluß der Wandereingänge lese ich 3 (+-1) aus. Dann habe ich mal einen Kondensator angeschlossen und verschieden geladen - schaut auch gut aus.

    Auch mit dem Wandlertiming lag ich falsch. Die Datenaufnahme dauert ca 300ns und die Wandlung danach noch mal 400ns. Also 700ns - bleiben 1300ns für das Auslesen. Die Interruptmethode habe ich verworfen - pollen bis Ready ist latenter. Das sind zwar nur 100ns, aber bei 1Mio mal lesen summiert sich das.

    Nächste Woche kommt ein Pulsgenerator ran - wenn die Kurven passen, dann steht für den Teil das Platinenlayout


    Dank Euch für die Hilfe

    PS: Ach ja - den SPI über Portoperationen zu emulieren - da habe ich max. 320 kS/s geschafft - aber nicht mit der bcm2835 lib, sondern mit direkten Speicherzuriffen.

    Einmal editiert, zuletzt von kutt (13. Juni 2014 um 16:42)

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!