Hallo zusammen!
Eine Frage an die Experten und alle mit guten Ideen:
Ich moechte folgendes in einem FPGA realisieren, brauche erst aber noch
ein paar Ideen und Anregungen um ein Konzept zu erstellen bevor ich
anfange etwas in VHDL zu schreiben:
Ich habe einen ADC an einem FPGA der mit 100MSPS/14bit sampled und zwar
immer 1000 Punkte nacheinander, extern getriggert mit 50Hz. In diesen
waveforms befinden sich 5us lange Rechteckpulse, die sich langsam, aber
nicht schnell veraendern duerfen, sonst soll eine Fehlermeldung
ausgegeben werden. Trigger, Datennahme und Darstellung auf einem PC
funktionieren schon, fuer den Rest brauche ich erstmal ein gutes
Konzept. Generell soll jede neue waveform mit der vorherigen verglichen
werden und falls diese irgendwo um mehr als einen bestimmten Wert
abweicht, ein Signal am FPGA ausgeben (daher eine Art pass/fail test).
Otpimal waere sogar ein punktweiser Durchschnitt ueber eine anpassbare
Anzahl von waveforms. Den Vergleich der aktuellen waveform mit dem
Durchschnitt der vorherigen wuerde ich ueber punktweise subtraktion und
anschliessendes aufsummieren des Ergebnisses machen, darauf dann ein
einstellbarer threshold. Das Problem da ist nur der Zeitjitter zwischen
den einzelnen Pulsen und dem Triggersignal, das koennen schonmal ein
oder zwei samples sein so dass bei der Subtraktion dort Spitzen
entstehen. Zu der Durchschnittsbildung ist mir ausser zwei
alternierenden Speichern aus denen dann die Differenz gebildet wird
nichts eingefallen, daher meine Frage an euch: Wie wuerdet ihr sowas
angehen?
Vielen Dank und schoenes Wochenende,
Jan
Ich verstehe das Problem nicht....
Lies mal deine Beschreibung so durch, als ob du dein Problem nicht
kennen würdest. Verstehst du das, was du geschrieben hast?
100MS/s und eine Speichertiefe von 1000 ergeben gerade mal 10us. In
diesen 10us kann also bestenfalls 1 solcher 5us Impuls sein. Und warum
wartest du dann anschließend 20ms (2000 mal so lang) und hoffst, dann
gerade mal wieder so einen Impuls erwischst... Seltsam.
Läuft das Signal nicht durch? Macht es dir gar nichts aus, solange
"blind" zu sein? Kurz: was ist das für ein Signal? Und vor allem: wenn
das ein Rechtecksignal ist, warum brauchst du einen ADC?
Hallo Lothar,
entschuldige meine etwas verworrene Formulierung, ich versuche es
nochmal was allgemeiner: Die Aufgabe ist es, ein Signal auf ploetzliche
Aenderungen zu ueberwachen. Dieses Signal ist ein Rechteckpuls von 5us
laenge der alle 20ms wiederholt wird. Dieser Rechteckpuls darf langsam
in der Amplitude driften, aendert diese sich aber von einem Puls zum
naechsten, soll es eine Fehlermeldung geben. Dahinter steckt eine
gepulste Hochspannungsanwendung, erzeugt werden Hochspannungsimpulse die
der Anwender langsam in Amplitude und Pulslaenge veraendern darf, gibt
es aber einen Ueberschlag, d.h. Teile des Pulses sind abgeschnitten,
soll der Generator abgeschaltet werden. Ein Triggerimpuls der den
Generator started ist vorhanden, diesen benutze ich auch um die
Digitalisierung des Pulses zu starten. Ich hoffe das war etwas
verstaendlicher :-)
Viele Gruesse,
Jan
Ich habs jetzt so verstanden ..
Du samplest alle 20ms ein Zeitfenster von 10µs.
Innerhalb diese Zeitfensters befindet sich ein 5µs Impuls.
Jetzt willst du die Amplitudendifferenz zweier aufeinanderfolgenden
Impusle wissen.
Also suchst du in deinen Samples die Anstiegsflanke und bildest den
Mittelwert bis zu Abstiegsflanke.
Da würde auch ein 1k Fifo hinter dem ADC und ein MC reichen.
Ja, so sieht das Problem aus, aber mit einer reinen Durchschnitsbildung
ist es nicht getan, es ist naemlich durchaus moeglich dass sich der
Rechteckpuls so verformt, dass das Integral immer noch dem des
vorherigen Pulses entspricht. Trotzdem waere es ein Fehlerfall in dem
abgeschaltet werden muesste. Ich denke man muss punktweise die Pulse
vergleichen. Leider gibt es keine Vorgabewerte wie Pulslaenge und
Amplitude aus denen ich einen Vergleichswert berechnen koennte bzw.
diese sind nicht ohne erhebliche Aenderungen am bestehenden System zu
bekommen.
Wenn jeder puls eine völlig andere Kurvenform
hat und du keine Vorgabe hast, wie er wirklich aussehen soll,
musst du im FPGA einfach einen Glaskugel Algo implementieren ;)
Berechne über eine bestimte Zeit eine mittlaufende mittlere Kurve.
Eventuell mit höherer Wichtung der zeitnahen Samples.
(n-1 x0,7; n-2 x 0,5 usw)
Aus dieser Kurve, wiederum ein Toleranzband für dein nächstes Sample.
Zusätzlich als Failsafe eine festes Toleranzband aus dem dein Sample
auch bei Langzeitänderungen nicht herausfallen darf.
...
Prinzipbedingt tritt der Fehlerfall sehr selten auf, im Schnitt jede
Stunde bei 50Hz Repetitionsrate. Der Anwender kann in dieser Zeit die
Amplitude und Pulslaenge stufenlos verstellen, allerdings nur um einen
bestimmten Betrag pro Zeit zwischen zwei Pulsen, sprich wie weit er das
Poti in 20ms drehen kann...
Die Frage ist nun, wie vergleiche ich am geschicktesten zwei Pulse im
FPGA, abwechselnd in ein FIFO kopieren und dann punktweise subtrahieren
und danach aufsummieren?
Hans-georg Lehnard schrieb:> Berechne über eine bestimte Zeit eine mittlaufende mittlere Kurve.> Eventuell mit höherer Wichtung der zeitnahen Samples.> (n-1 x0,7; n-2 x 0,5 usw)> Aus dieser Kurve, wiederum ein Toleranzband für dein nächstes Sample.> Zusätzlich als Failsafe eine festes Toleranzband aus dem dein Sample> auch bei Langzeitänderungen nicht herausfallen darf.
Exakt das ist es was ich suche, nur wie programmiere ich das am besten?
Bevor du anfängst zu Programmieren mach dir erst einmal klar wieviel
Speicher du brauchst.
Dein Impuls ist 500 samples lang und hat 14 Bit.
Du brauchst Speicher für die Festwertkurve, für den laufenden
Mittelwert,
und wenn du über 100ms mitteln willst noch ein Ringbuffer für 5 Kurven.
Die Toleranzbänder kannst du durch Addition von Konstanten auf jedes
Sample bestimmen.
Also 7 x 500 x 14 Bit Speicher wenn du ein Fpga verwenden willst.
oder 7 x 500 x 2 Byte (16 Bit) bei einem MC.
Jetzt fragst deinen Chef, wieviel Geld er ausgeben will und wie lange du
Zeit hast ..
Dein FPGA programmierst in VHDL
und den MC in C ;)
JanK schrieb:> Exakt das ist es was ich suche, nur wie programmiere ich das am besten?
Das ist ein gleitender Mittelwert: du hast z.B. die Summe von 16 Werten
in einem Puffer. Zum Eintragen eines neuen Wertes ziehst du davon 1/16
ab, und addierst dann den neuen Wert dazu. Diese 16 Elemente kommen
nicht von ungefähr: es sollte eine Zweierpotenz sein, denn dann ist die
nötige Division vor der Subtraktion nur ein Ignorieren niederwertiger
Bits...
Ich habe das hier mal in C aufgeschrieben:
http://www.lothar-miller.de/s9y/categories/21-Filter
Ind VHDL ist das genausolang... ;-)
Hans-georg Lehnard schrieb:> Bevor du anfängst zu Programmieren mach dir erst einmal klar wieviel> Speicher du brauchst.
Man speichert ja nicht die Rohdaten, sondern das, worauf es (offenbar)
ankommt: die Pulsdauer. Und das ist nur eine Zahl mit max. 16 Bit...
@Hans-Georg: Also Hardware ist vorhanden, ein XC5VLX110T board mit ADCs
und 128MB RAM, sollte also reichen :-) Vom Prinzip her hast Du genau
erklaert was ich haben moechte, jetzt versuche ich ich erstmal an einem
Blockdiagramm um zu sehen wie ich das in Module einteilen kann.
@Lothar: Vielen Dank fuer Deine Idee, aber die Pulslaenge alleine reicht
nicht, es ist eher sowas wie ein Maskentest nur dass die Maske als
Toleranzband um den Mittelwert der vorherigen Pulse staendig neu
berechnet wird.
Ich würde den Algorithmus erstmal testen. Dazu braucht man ein paar gute
Testsignale (mit und ihne Fehlerfall). Am Besten wäre ein
parametrierbares Modell, mit dem Du alle Testsignale nach belieben
erzeugen kannst.
Als Algorithmus würde ich mal ein Blick auf die
Kreuzkorrelationsfunktion (KKF) werfen.
Duke