Forum: Mikrocontroller und Digitale Elektronik ADC mit Raspberry Pi kontinuierlich auslesen


von Nick (Gast)


Lesenswert?

Guten Abend zusammen,


ich habe einen Raspberry PI 3 B+, welcher einen A/D-Wandler über SPI 
ausliest. Die SPI-Verbindung taktet mit knapp 16MHz das sind etwa 1MSps 
die vom ADC pro Sekunde erhalten werden (Das zu Sampelnde Signal ist 
rel. hochfrequet weshalb tatsächlich 1MSps benötigt werden). Aufgrund 
der Geschwindigkeit übernimmt der automatische DMA Controller das 
Auslesen (dieser springt bei der BCM2835 Library, die ich verwende 
automatisch bei über 96 gesendeten Bytes an).


Um eine möglichst lange Messdauer zu erreichen, übergebe ich der SPI 
Schnittstelle ein möglichst langes Array, damit dieses vom ADC mit den 
Messwerten gefüllt wird und an mich zuück geliefert wird. Das Problem 
ist allerdings, dass die Messung dann nur etwa ein paar Sekunden dauert 
und ich gerne längere Zeiträumen abdecken will. Gibt es eine Möglichkeit 
das so zu lösen, dass der ADC quasi kontinuierlich (15-20 Sekunden 
beispielsweise) das Signal sampeln kann? Dabei darf es jedoch auf keinen 
Fall zur Unterbrechung des Samplings kommen.

Der Befehl an den ADC sieht derzeit wie folgt aus
Code

    char tx0[8200000] = {};
    char rx[] =  {};
    bcm2835_spi_transfernb(tx0,rx,samples);

Vielen Dank schon einmal vorab für eure Hilfe :)

: Verschoben durch Moderator
von Olaf (Gast)


Lesenswert?

Du muesst deinen Treiber so umprogrammieren das der DMA mit mehren 
Buffern arbeitet. Dann fuellt der DMA einen Buffer und den anderen 
leerst du gerade.

Ausserdem muss der DMA einen IRQ liefern der jedesmal zuschlaegt wenn 
der Buffer voll ist und sehr schnell den neuen Transfer aufsetzt.

Mit Mikrocontrollern ist sowas moeglich. Ob es auch mit dem Linuxkernel 
moeglich ist weiss ich nicht, wuerde es aber erwarten weil das ja auch 
in anderen Bereichen (Audio/Video-Ausgabe) gebraucht wird.

Olaf

von Blabla (Gast)


Lesenswert?

Also ich denke nicht das es mit dem Linux Kernel da ein Problem gibt, 
deine Netzwerk Verbindung läuft ja auch schneller.
Es hängt einzig und allein an den Fähigkeiten des Entwicklers. Wenn du 
im User Space bist ist deine Anwendung tendenziell etwas langsamer wie 
wenn du einen Kernel Treiber schreibst.
Jedoch sollte deine Strategie nicht sein ein möglichst langes Array zu 
verwenden, sondern lieber eine Strategie zum Puffern und weitergeben von 
Daten. Also eine Art streaming implementieren, zum Beispiel könntest du 
bei den ganzen SDR Anwendungen schauen wie die das machen. Schliesslich 
kommen die ja auch mit mehr als 1Msps klar und rechnen dann noch auf den 
Daten.

DMA, Double buffering, circular buffer, streaming, coroutines, 
asynchronous I/O könntest du mal als weitere Schlüsselwörter zur Suche 
verwenden.

Was ich mich Frageist, was soll es werden. Eine dauerhafte Beobachtung 
oder reicht es den RAM voll laufen zu lassen und dann die Daten weg zu 
schreiben?
Für den Anfang könntest du ja mal probieren mehrere Arrays anzulegen und 
dann einfach den spi Befehl mehrfach wiederholen, oder einfach ein Array 
aus Arrays bauen und mit einer Schleife drüber laufen bis du deine 2O 
Sekunden hast. Wahrscheinlich nicht schön aber könnte reichen.

Interessant wäre zu wissen wie viel Byte pro Sample übertragen werden 
und ob es Overhead gibt? Relativ Hochfrequent ist ein guter Witz, was 
ist denn die erwartete höchste Signalfrequenz die du messen möchtest?

Mit deinem Array festgelegter Länge solltest du ja auch in der Lage sein 
auszurechnen wie lange du Daten aufzeichnen kannst, etwa ein paar 
Sekunden ist eine schlechte Angabe.

Ich gehe mal von einem 16bit ADC, wegen der 16MHz zu 1MSPS Beziehung 
aus, es könnte evtl Sinnvoll sein einen MC dazwischen zu setzen der 
deinen langsamen aber kontinuierlichen Datenstrom aufzeichnet und dann 
am besten per DMA in Blöcken schneller weiter gibt z.B. könntest du dann 
eine gpio Pin setzen wenn wieder ein Datensatz zur Abholung bereit 
steht. So kannst du trotz Raspi CPU Auslastung einen sauberen Datenstrom 
sicherstellen.


Wäre schön etwas von der Lösung später auch wieder hier zu sehen.

von Gustl B. (-gb-)


Lesenswert?

Hat das SPI im Rπ einen RX Buffer? Normalerweise gibt es sowas. Dann 
gehst du periodisch hin, guckst ob was in diesem Buffer steht und liest 
es aus. Dann wartest du wieder. Mit Python kann ich so ganz ohne DMA 12 
MBit von einem FT2232H UART lesen, dauerhaft.

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.