Frage zur Signalverarbeitung



  • Hallo,

    ich habe fortlaufende Daten von 0 bis 1 im Fließkommaformat. Nun möchte ich folgende Bedingung abfragen können:

    * Gab es einen langsamen Übergang von 0,2 bis 0,4. Wobei ich langsam natürlich per Zeitkonstante festlegen will.

    Ich glaube, das fällt in den Bereich der Signalverarbeitung. Kann mir da wer bei der Lösung helfen?



  • Sind die Messungen "kontinuierlich", also in festen Abständen?
    Schwank das Signal oder steigt es nur monoton an? Was ist dann mit Schwankungen zwischen 0,2 und 0,4, sollen die ignoriert werden oder willst du nur monotone Wechsel von 0,2 auf 0,4 erkennen können?



  • Die Messwerte komme in festen Intervallen rein. Es handelt sich um Werte von einem Neigungssensor und ich will feststellen ob "langsam" ein bestimmter Winkelbereich durchlaufen wurde. Schwankungen und Spitzen können vernachlässigt werden, da ich dann mit der Exponentielle Glättung arbeite.



  • Wenn ich dich richtig verstanden habe, würde es reichen, die Anzahl der Intervalle mitzuzählen, in denen die Messwerte zwischen 0,2 und 0,4 liegen.
    Das schützt dich allerdings nicht davor, wenn diese die gewünschte Zeit lang wild (bzw. schnell) in dem Bereich hin- und herschwanken, aber das soll ja vernachlässigt werden. Bei Spitzen (Wert ist über 0,4 aber wurde zu schnell erreicht) würde der Code wieder neu anfangen zu zählen.

    Hier wär ein Beispielcode:

    const int tresh = 10000;  // deine Zeitkonstante
    int count = -1;  // oder long. -1 signalisiert, dass der Wert noch nicht unter 0,2 war.
    while (1) {
        float val = get_value();  // bzw. double
        if ( val < 0.2f ) {  // ohne f, wenn du mit doubles arbeitest
            count = 0;
        } else if ( val > 0.4f ) {
            if ( count == -1 ) continue;  // plötzlicher Sprung auf Wert über 0,4: count bei -1 belassen
            if ( count >= tresh )  {  // gewünschte Anzahl Intervalle erreicht oder überschritten
                count = -1;
                do_action();  // oder was auch immer, z.B. break, um die Schleife zu verlassen
            } else {
                count = -1;
            }
        } else {  // Wert liegt im Bereich
            if ( count == -1 ) continue;  // ... aber war noch nicht unter 0,2: count bei -1 belassen
            ++count;
        }
    }
    


  • Evtl. macht es Sinn, mit einem Referenz-/Wunschsignal im Zeitbereich zu vergleichen; evtl. nachdem Du vorher den ganzen hochfrequenten Spaß aus deinem Signal mit nem Tiefpaß rausgeworfen hast.

    Oder Zeitbereich fenstern und im Frequenzbereich draufgucken, ob Du deine "Zeitkonstante" findest und die Amplituden passen (Gabor-Transformationen oder so). Scheint mir aber rechter Overkill.



  • Das sind wirklich nette Möglichkeiten das Problem zu lösen, das werde ich mal implementieren und dann testen, danke dafür.



  • Hier ist noch eine Veränderung, die dich davor schützt, dass die Folge (0,199, 0,399, 0,399, 0,399, ..., 0,399, 0,401) als langsamer Übergang erkannt wird, indem als zusätzliche Bedingung der Abstand max_diff zum vorigen Messwert nicht zu groß werden darf:

    const int tresh = 10000;  // deine Zeitkonstante
    const float max_diff = 0.2f / (tresh / 2);  // bzw. double (dann auch das f weglassen)
    int count = -1;  // oder long. -1 signalisiert, dass der Wert noch nicht unter 0,2 war.
    float last_val;  // bzw. double
    float val = get_value();   // bzw. double
    if ( val < 0.2f ) count = 0;  // erste Überprüfung kann stark vereinfach werden
    while (1) {  // diese Schleife verarbeitet nun alle Überprüfungen ab der zweiten
        last_val = val;
        val = get_value();
        if ( val < 0.2f ) {  // ohne f, wenn du mit doubles arbeitest
            count = 0;
        } else if ( val > 0.4f ) {
            if ( count == -1 ) continue;  // plötzlicher Sprung auf Wert über 0,4: count bei -1 belassen
            if ( abs(val - last_val) > max_diff ) {  // Wert ist zu stark gesprungen: auf -1 setzen
                count = -1;
                continue;
            }
            if ( count >= tresh )  {  // gewünschte Mindestanzahl Intervalle erreicht
                count = -1;
                do_action();  // oder was auch immer, z.B. break, um die Schleife zu verlassen
            } else {
                count = -1;
            }
        } else {  // Wert liegt im Bereich
            if ( count == -1 ) continue;  // ... aber war noch nicht unter 0,2: count bei -1 belassen
            if ( abs(val - last_val) > max_diff ) {  // ... aber ist zu stark gesprungen: auf -1 setzen
                count = -1;
                continue;
            }
            ++count;
        }
    }
    

    edit: Uups, hab prompt vergessen, das Entscheidende für die Änderung einzubauen. 😃



  • ganzLangsam# schrieb:

    Das sind wirklich nette Möglichkeiten das Problem zu lösen, das werde ich mal implementieren und dann testen, danke dafür.

    Gerne 🙂


Log in to reply