Perimeter Startlinienerkennung

Der "Precision Peak Detector" wäre vielleicht auch etwas. Dann bräuchte man das Maximum nicht "suchen". "Löschen" des Maximums geht mit dem Schalter.

peak_hold.jpg

Attachment: https://forum.ardumower.de/data/media/kunena/attachments/905/peak_hold.jpg/
 
Zuletzt bearbeitet von einem Moderator:
Ich habe mich heute auch mal daran gemacht um die aktiven Filter in LTSpice abzubilden.

Filter.png


Jedoch ist halt die Frage, wie sehr man mit diesem Filter gegen eine Lichtmaschine gewapnet ist, die eine Leistung von 2 bis 3 kW besitzt. Darum habe ich etwas respekt vor einem reinen Amplitudentrigger.


Der Precision Peak Detector sieht wirklich gut aus und vorallem ohne Rechenaufwand. Ich werde die Software auf jeden Fall mal die nächste Tage testen! Super, danke.

Wäre es nicht irgendwie möglich eine vereinfachte FFT mit weniger Bins und einem höherfrequenten Signal mit 16 MHz abzubilden? Ich könnte mich auch mit einer Messung der Zeit von 0,01 Sekunden zufrieden geben. Genauigkeit des signal ist mir dann doch wichtiger eines eine Messung im Millisekundenbereich.
Attachment: https://forum.ardumower.de/data/media/kunena/attachments/4008/Filter.png/
 
Zuletzt bearbeitet von einem Moderator:
Ich habe heute mal die FFT Funktion angeschaut. Wenn ich einen Prescale 64 verwende und 128 Bins benötigt dies 0,006 s für die Abtastung. Dabei habe ich eine Bandbreite von 150 Hz, was meiner Meinung nach auch akzeptabel ist.

Jetzt muss ich mich noch ein bisschen mit dem Code beschäftigen. Ganz trivial finde ich ihn leider nicht.
 
Hallo Roland,

danke für das Patent. Ich werde es mir mal die Woche durchlesen. Ist auf jeden Fall einfacher zu verstehen als der fft code ;)

Jedoch ist Code meistens billiger als Komponenten ;) vorallem wenn ich sehr viele davon benötige. Daher werde ich parallel an der FFT weiterarbeiten.

Ich habe aber heute mal den Code von reciever2, den Alexander hochgeladen hat, kompilieren lassen. Dabei habe ich recherchiert, dass WProgram.h durch Arduino.h ersetzt werden muss. Das hat der dumme Maschinenbauer noch hinbekommen ;)
Jetzt habe ich aber eine Fehlermeldung in der fix_fft.cpp bekommen, dass Sinwave nicht deklariert wurde. Jedoch wird das doch mit const prog_int8_t Sinewave[N_WAVE] PROGMEM getan.

Da ich den Code nicht selber geschrieben habe, sondern von einem Profi bekommen habe, geh ich davon aus, dass es nur ein kleiner Fehler ist.

Dann habe ich noch einen reciever4 gefunden. Beim Kompilieren tritt der gleiche Fehler auf. Aber was mich wundert, ist das hier register definiert werden. Bei reciever2 wird das nicht gemacht. Ist es also nicht nötig sie zu definieren? Oder habe ich Nachteile wenn ich es nicht tue.
Attachment: https://forum.ardumower.de/data/media/kunena/attachments/4008/Fehlermeldung_reciever2.txt/
 
Zuletzt bearbeitet von einem Moderator:
http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__pgmspace_1ga48c7cb011ea5f82f4b73df40e07dff46.html

Sieht so aus, als ob prog_int8_t nicht mehr unterstützt wird.

Oder:
The typedef is only visible if the macro __PROG_TYPES_COMPAT__ has been defined before including (either by a define directive, or by a -D compiler option.)
 
Habe jetzt mal die reduzierte Filterschaltung getestet.

Aufbau: Ich habe den LM386 Amplifier vor einen aktiven Tiefpass und einen aktiven Hochpass gehängt. Als OP habe ich einen LM358 verwendet und mit 5V betrieben.

In den nachfolgenden Bildern sind die gemessenen Signal zu sehen, die eigentlich ganz gut sind. Jedoch ist das Signal nach den Filtern deutlich geschwächt, obwohl ich eine Verstärkung von 2 haben sollte.

Nun zur Filterung: Ich habe die Schaltung ohne und mit Filter mit dem Fön getestet.
Resultat: Ohne den Filter hatte ich einen Ausschlag nach 10 cm Annäherung. Mit dem Filter konnte ich das auf 3 cm reduzieren.

Ich werde jetzt dann mal die doppelte Filterung ausprobieren und dann das Signal nachträglich mit einem zweiten LM386 verstärken.
Attachment: https://forum.ardumower.de/data/media/kunena/attachments/4008/IMG_20170123_202743.jpg/
 
Zuletzt bearbeitet von einem Moderator:
Ich habe nun das Signal mit einem zweiten LM386 getestet. Ich habe die zweit LM386 direkt hintereinander gehängt. Jedoch bekomme ich dann kein Signal mehr. Nach dem erstem LM386 habe ich volles Signal, am zweiten nix mehr. Wenn ich den LM386 hinter den Filter hänge habe ich ein ganz anderes Problem. Durch den Filter bekomme ich über die Entfernung zur Schleife keine kontinuierliche Signalverstärkung. Das Signal reagiert erst ab einer geringen Entfernung von 20 cm (ohne Filter komme ich auf über einen Meter). Unterhalt dieser Entfernung ist der Gradient der Signalverstärkung sehr stark, so das eine Verstärkung des Signals nach der Filterung keinen Sinn macht.

Hat einer von euch eine Idee, warum das Signal nach der Filterung eine "Durchbruchschwelle" aufweist? Würde das nicht der Fall sein, könnte ich das Signal nachträglich verstärken.

Parallel würde ich gerne die FFT aus reciever2 testen. Jedoch muss ich den Code ein bisschen umschreiben. Kann mir einer sagen was der Rückgabewert der FFT Funktion ist und was zurückgegeben wird?
 
Ich habe das Problem mit dem "Durchbruchsignal" gelöst. Ich habe die Widerstände R1 und R2 der Filterschaltungen, welche für die Verstärkung zuständig sind, weggelassen, da sie sowieso den gleichen Wert haben. Jetzt funktioniert der Filter besser.

Jedoch muss ich sagen, dass die Filterung mangelhaft ist. Ich habe jetzt den Fön gegen einen Akkuschrauber getauscht, da ich mir nicht sicher war ob das Signal des Föns mit 1,8 kW bei 230 V zu stark ist. Der Schrauber ist jedoch noch viel schlimmer. Trotz zweifacher Filterung darf ich mich mit dem Akkuschrauber keine 10 cm nähern.

Oder hat jemand eine Idee für einen effektiveren Filter als ein aktiver Filter.

Daher würde ich es gerne mit der FFT versuchen.
 
Hallo Alexander,

ich habe ein Problem mit dem Verständnis des FFT Code des Sender2. Was ist der Ausgabewert der FFT? Und was wird ausgegeben? Den Wert der Frequenz und die Amplitude?

Die Filter waren einfach zu schwach.

Vielen Dank für deine Hilfe!

1. Die FFT-Analyse benutzt die ADC-Samples und führt eine abschnittsweise Frequenzanalyse durch. Pro "FFT-Bin" werden also mehrere Frequenzen zusammengefasst (Bandbreite eines Bins). Das Ergebnis der FFT pro FFT-Bin ist eine Analyse eines periodischen Wechselsignals in dieser, genauer:
1. der Realteil und
2. der Imaginärteil des periodischen Wechselsignals zu einem Zeitpunkt t (Start der Samples).
Man kann sich dazu ein einzelnes Signal als Zeiger auf einem Kreis/einer Uhr vorstellen, Real- und Imaginärteil sind die jeweiligen Abschnitte auf X- und Y-Achse. Die Berechnung der Amplitude (Kreisradius/Betrag des Zeigers) folgt im Punkt weiter unten.
Zeigerbild01.png
http://www.schule-bw.de/unterricht/...erial/e_lehre_2/wechselstr/zeigerdiagramm.htm http://www.lntwww.de/sitemap.html (Kapitel 4.2)

Mit Real- und Imaginärteil ist also die aktuelle Position des periodischen Wechselsignals eindeutig beschrieben. Phase und Amplitude können wir daraus herleiten.

Die Anzahl "FFT-Bins" legt fest für wie viele Abschnitte die Frequenz-Analyse durchgeführt wird, legt also die kleinste Bandbreite der Analyse fest. Die Anzahl Bins muss immer 2^X ergeben. Beispiel: Wir wollen für 256 FFT Bins analysieren:


Code:
// number of FFT bins (2^8 - see FFT call)
#define FFTBINS 256


2. Rechnen wir als nächstes aus wie groß die Bandbreite eines FFT-Bins damit ist. Wir wählen eine Sample Rate von 19 Khz. Damit erhalten wir folgende Berechnung für die Bandbreite eines FFT-Bins:


Code:
// ADC sampling rate (Hz) (has to match ADC setup below)
#define F_SAMPLERATE 19231.0

// bandwidth per FFT bin (75.12109375 Hz)
const double F_BANDWIDTH = ( F_SAMPLERATE / FFTBINS )  ;


3. Welches FFT-Bin enthält nun die Bandpass-Analyse für unsere gesuchte Frequenz (7 Khz). Dies berechnen wir wie folgt:


Code:
// choosen bandpass center frequency (f0) (Hz)
#define F_BANDPASS 7812

const int FFTBIN = ( F_BANDPASS / F_BANDWIDTH + 0.5) ;


Das Ergebnis ist die Nummer des FFT Bins für unsere gesuchte Frequenz.

4. Jetzt haben alle Berechnnungen gemacht und können den FFT starten. Ein Array enthält den Realteil (samples) und ein weiteres den Imaginärteil (im) für alle Bins. Der FFT kann die Analyse nur bis zur halben Abtastfrequenz durchführen (FFTBINS/2). Wir berechnen die Amplitude des FFT-Bins mit Wurzel aus "Realteil^2 + Imaginärteil^2" (Pythagoras).

Ich hoffe jetzt macht alles Sinn? ;-)


Code:
char samples[FFTBINS];
char im[FFTBINS];

    fix_fft(samples, im, 8, 0);          

    for (byte i=0; i < FFTBINS/2; i++){      
      int v = sqrt(samples[i] * samples[i] + im[i] * im[i]);
      if (i > 0) { // ignore 50 Hz band
        // find overall frequencies peak (test)
        if (v > testv){
          testv = v;
          testBin = i;
        }
      }
      if (i == FFTBIN) {
        // bandpass
        //analogWrite(LED, min(255, v));
        mag[channel] = v;
        switch (channel) {
          case 0: analogWrite(OUT0, v); break;
          case 1: analogWrite(OUT1, v); break;          
          case 2: analogWrite(OUT2, v); break;                    
          case 3: analogWrite(OUT3, v); break;                    
        } 
        peak[channel] = max(peak[channel], v);                         
        if (v > 20) digitalWrite(LED, HIGH);          
          else digitalWrite(LED, LOW);
      }            
    }

Attachment: https://forum.ardumower.de/data/media/kunena/attachments/905/Zeigerbild01.png/
 
Zuletzt bearbeitet von einem Moderator:
Wahnsinn! Du solltest Dozent werden. Ich glaub ich habe es verstanden, darum habe ich es noch mal zur Kontrolle zusammengefasst.

Ich betrachte also nur das FFT Bin und schau auf die Amplitude?


FFTBin.png



Jetzt habe ich jedoch noch eine Frage zum Code.


Code:
for (byte i=0; i < FFTBINS/2; i++){      
      int v = sqrt(samples[i] * samples[i] + im[i] * im[i]);
      if (i > 0) { // ignore 50 Hz band
        // find overall frequencies peak (test)
        if (v > testv){
          testv = v;
          testBin = i;
        }
      }


Warum betrachte ich hier alle Bins? Mich interessiert doch eigentlich nur das FFT Bin!?!

Kann ich nicht einfach:


Code:
int v = sqrt(samples[FFTBIN] * samples[FFTBIN] + im[FFTBIN] * im[FFTBIN]);

      if (v = TRIGGER){
      int i = 1;}
      else{
      int i = 0;}

Attachment: https://forum.ardumower.de/data/media/kunena/attachments/4008/FFTBin.png/
 
Zuletzt bearbeitet von einem Moderator:
:) Da hast Du recht, es reicht den einzelnen FFT-Bin zu betrachten. Das suchen der maximalen Amplitude über alle FFT-Bins hatte nur den Sinn einer Fehleranalyse und war nur gedacht um zu erkennen ob wir den richtigen FFT-Bin berechnet haben. Jeder hatte ja etwas andere Bauteile verwendet und daher war nie ganz klar in welchem FFT-Bin wir landen. So konnte man also schnell in der seriellen Konsole sehen ob man die Frequenz getroffen hatte.
 
Naja, es kommt wie es kommen muss. Ich habe schon wieder eine Verständnisfrage.

Alexander schribet:
Der FFT kann die Analyse nur bis zur halben Abtastfrequenz durchführen (FFTBINS/2).

Wenn ich also mit 19 kHz abtaste, kann ich also eine Frequenz von bis zu 9500 Hz. Aber was hat es mit den FFTBINS/2 zutun? Die sind doch erstmal unabhängig von der Abtastfrequenz!?

Ich habe jetzt mal versucht die FFTBINS auf 128 herunter zusetzten, dann geht aber leider nix mehr. Auch wenn ich parallel die Abtastrate auf 9 kHz heruntersetze geht es nicht. Was habe ich da nicht verstanden?

Ich dachte die FFTBINS und die Abtastfrequenz hängen nur über die mögliche Auflösung zusammen.


Code:
F_BANDWIDTH = ( F_SAMPLERATE / FFTBINS )



Nachtrag: Ich habe das ganze jetzt auch mit verschiedenen Abtastraten (bis 76800 Hz) versucht. Bei 256 FFTBINS funktioniert alles super. Sobald ich aber auf 128 oder 512 gehe, erscheint keine Meldung mehr im seriellen Monitor.
 
Hallo zusammen,

so, ich habe das Problem jetzt einfach umgangen, indem ich einen Prescale 32 in Kombination mit 256 Bins gewendet habe. Dies ist für die Geschwindigkeit sowie die Bandbreite gleich wie Prescale 64 mit 128 Bins. Damit komme ich auf eine FFT Abtastzeit von 0,06 s. Die Zeit zur Auswertung werde ich die nächsten Tage mal messen.

Die Filterung mit der reduzierten FFT funktioniert echt gut! Ich bekomme im seriellen Monitor ein Wert von 13 wenn ich einen Abstand von 70 cm einstelle. Wenn ich den Fön oder den Akkuschrauber an die Spule halte, bekomme ich einen maximalen Ausschlag von 5.


Nun ist mir noch eine weitere Idee gekommen, wie ich die Filterung auf ein kleiner Band reduzieren ohne eine längere Auswertezeit zu benötigen. Nach meiner Suche nach einem effektiven elektrischen Filter, bin ich auf den Cauer-Filter gestoßen. Dieser hat bei einer bestimmten Frequenz einen starken Abfall. Jedoch nur in Richtung der hohen Frequenzen. Für die untere Schwelle möchte ich jedoch dann die FFT verwenden. Den Filter werde ich jetzt mal simulieren und dann die Teile für einen ersten Test besorgen.


FFT_Cauer.png

Attachment: https://forum.ardumower.de/data/media/kunena/attachments/4008/FFT_Cauer.png/
 
Zuletzt bearbeitet von einem Moderator:
Da bin ich gerade auch überfragt warum mehr oder weniger Bins nicht gehen.

Übrings: als Alternative zur FFT gibt es noch den Goertzel Algorithmus welcher schneller läuft weil er nur eine Frequenz betrachtet. Unbedingt mal ansehen ;-)
https://github.com/jacobrosenthal/Goertzel
 
Den Goertzel Algorithmus habe ich mir mal angeschaut und ist echt gut zu verstehen, jedoch habe ich noch ein paar Probleme ihn auf dem Arduino zum laufen zu bekommen. Aber das werde ich hoffentlich diese Woche noch hinbekommen.

Währenddessen habe ich eine Trägerplatine für den Transponder aufgebaut. Der Transponder enthält derzeit einen DC DC Booster um die Lipospannung auf 5V zu heben, den Verstärker für das Spulensignal, einen Arduino Pro Mini und ein 433 Mhz Modul um die Daten zu versenden.

Prototyp.jpg


In einer nächsten Version werde ich den Verstärker und den DC DC Booster auf der Platine integrieren.
Attachment: https://forum.ardumower.de/data/media/kunena/attachments/4008/Prototyp.jpg/
 
Zuletzt bearbeitet von einem Moderator:
Oben