Moin,
Christoph M. schrieb:> Welche besseren Methoden gibt es?
Programmiersprache verwenden, in der man das Gewurschtel mit dem ADC in
einer Tickerinterruptroutine machen kann.
Gruss
WK
Christoph M. schrieb:> Welche besseren Methoden gibt es?
In aufsteigender Geschwindigkeit:
* Function mit native decorator
* Function mit viper decorator
* Asm-Function mit asm_thumb decorator
* DMA in einen Buffer
* DMA in einen Ring-Buffer
* DMA in zwei wechselnde Buffer
Höchste erzielte Geschwindigkeit: 3Msps.
Weit außerhalb der Spezifikation und mit zunehmend schlechterer
Linearität.
PS. Nicht auf Leute hören, welche offensichtlich keinerlei Erfahrung mit
einer Programmiersprache haben.
Norbert (der_norbert)
>Nur mal als kleine Richtungsangabe.
Das ist ein super Richtungsangabe, danke :-)
Ich habe mal versucht, das Ganze in eine Klasse zu packen, damit man es
als externes Modul benutzen kann.
Als Klasse scheint es aber etwas langsamer zu werden:
1
sampling time: 2.004 µs
2
sampling frequency: 499002 Hz
3
sampling time: 2.006 µs
4
sampling frequency: 498504 Hz
5
sampling time: 2.006 µs
6
sampling frequency: 498504 Hz
7
sampling time: 2.005 µs
Am einfachsten wäre meiner Meinung nach folgende Form:
1
import fastAdc
2
laenge=1000
3
fs=500000
4
adc=fastAdc.FastAdc()
5
print(adc.get_samples(laenge,fs))
Ich habe es aber nicht geschafft, die Array-Initialisierung in die
Klasseninitialisierung zu verschieben, weil Viper scheinbar ein Problem
mit dem Array als Klassenvariable hat.
Christoph M. schrieb:> Als Klasse scheint es aber etwas langsamer zu werden:
Die paar Nanosekunden sind lediglich eine Meßunschärfe. Sieht man sobald
größere Mengen (50_000) gesammelt werden.
Christoph M. schrieb:> Ich habe es aber nicht geschafft, die Array-Initialisierung in die> Klasseninitialisierung zu verschieben, weil Viper scheinbar ein Problem> mit dem Array als Klassenvariable hat.
Array in __init_() errichten und dann mit self referenzieren.
Viper kann das problemlos.
Hab mal ein wenig modifiziert.
Christoph M. schrieb:> Was ist vom Timer-Interrupt zu halten?
Viel zu lahmarschig, meiner Meinung nach.
Da kannst du besser den ADC Pacing Timer im Register setzen. Ist um
Größenordnungen präziser und einfacher.
Register DIV (0x10 >> 2) unterhalb der _ADC_BASE.
> fastadc.py (2,03 KB)>Hab mal ein wenig modifiziert
Das Array scheint problematisch. es gibt nur einen Rückgabewert (ich
nehme an der Pointer auf das Array? ):
Danke für die Antwort.
Jetzt ist das Problem, dass ich das array in ein json array umwandeln
will:
1
json.dumps(signal)
Das klappt aber nicht mit dem u16 Format, welches "get_samples" zurück
liefert.
Eine Möglichkeit, die mir einfällt aber recht unelegant erscheint ist,
eine Funktion zu in der FastADC Klasse zu implementieren, mit der ich
Einzelwerte abholen kann:
1
@micropython.viper
2
def get_sample(self,idx):
3
values: ptr16 = ptr16(self.values)
4
value: int = self.values[idx]
5
return value
und dann sie dann mühsellig mit hohem Speicherverbrauch umzuwandeln:
Du musst keine Klimmzüge veranstalten um auf die Daten des Arrays
zuzugreifen.
Einfach nur mit values[index].
Dein JSON String besteht einfach nur aus einer Auflistung der Werte,
Komma-getrennt.
Du brauchst also bis zu fünf mal soviel Speicherplatz wie du Werte im
Array hast (0…4095 + ,).
Oder noch einfacher:
>Du musst keine Klimmzüge veranstalten um auf die Daten des Arrays>zuzugreifen.
Vielen Dank. Irgendwie geht es ja meistens einfach mit Python. Die Kunst
ist nur, die richtige Funktion zu finden.
Im Anhang mal den Screenshot des Signals mit einem PiPico W gesampelt.
Hier mal die vollständigen Sourcen für eine Art "PiPico Oszi".
Eine PiPico W wird als Access-Point konfiguriert auf den man dann autark
zugreifen kann.
>Ich habe nur mitgelesen, aber: Was für ein Qualitätbeitrag, Norbert.
Ich finde die sarkastische Antwort von Norbert durchaus passend, denn
immerhin hat er gezeigt, wie sich das Problem in Micropython auf
elegante Art lösen lässt. Außer dümmliche Kommentare, die an der
Eingangsfrage vorbei gehen, hat ja ansonsten niemand zur Lösung
beigetragen
Vielleicht hat jemand Erfahrung damit: Kann man mit Micropython
kontinuierliche Signalverarbeitung machen?
z.B:
Via DMA ein Microphon samplen und dann mit Blocksignalverarbeitung einen
Goertzel Algorithmus oder einen Bandpassfilter laufen lassen.
ADC DMA:
https://iosoft.blog/2021/10/26/pico-adc-dma/
Christoph M. schrieb:> Goertzel Algorithmus
Goertzel geht prima, hatte ich vor geraumer Zeit schon gemacht.
Habe aber im Moment keine Meßwerte zum Zeitverhalten.
Es war aber, selbst ohne Optimierung, schon recht flugs.
Wenn man dann noch den zweiten Kern bemüht…
Heute bin ich zufällig auf einen Vortrag des Micropython-Gründers
gestoßen:
https://www.youtube.com/watch?v=iEQQWpjgFd8
Laut ihm gibt es eine Kooperation mit der ESA, die Micropthon in
Satelliten einsetzen will.
Nun, die Beispiele im Zwischennetz sind vermutlich alle veraltet.
Wie der ADC in den Ecstasy-Mode versetzt wird, hatten wir ja schon.
Als Data-Request Quelle (treq_sel) muss je nach µC DREQ_ADC:48 oder
DREQ_ADC:36 gesetzt werden.
Im ADC: FCS Register einmal DREQ_EN einschalten.
Soweit aus der Erinnerung…
Datenblatt studieren hilft bei jeder Programmiersprache. ;-)