Frequenz messen Anemometer

fiftyone_88

Level-1
Beiträge
23
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo miteinander, zuerst einmal möchte ich euch begrüßen. Ich studiere Windenergietechnik und in einem Messtechnik Labor habe ich die Aufgabe bekommen einen Algorithmus in Strukturiertem Text zu verfassen, um mit Hilfe von Codesys die Windgeschwindigkeit eines Anemometers zu messen, der an einem Raspberry Pi angeschlossen ist.

Der Anemometer gibt ein Rechtecksignal aus, von der ich die Frequenz bestimmen muss. Diese Frequenz ist proportional zum Wind ist ... Auf diese Geschichte möchte ich jetzt tiefer eingehen, es geht mir nur um die Frequenz.

Das folgende Schaubild an:

attachment.php


Mein Algorithmus:

var

LED,a:BOOL;
z:BYTE:=10;
ton0:TON



LED:=PiFace.byIn.4; (*Eingangssigsignal*)

IF (LED=1) THEN a:=1; END_IF; (*setzen einer Variablen (notwendig für dennächsten Schritt*)
IF (z=1) THEN a:=0; END_IF; (*a auf Null setzen, damit er nicht wieder in diese Bedingung rutscht, wenn z=1 *)
IF (a=1) AND (LED=0) THEN (*Bedingung um genau zum Zeitpunkt P0 anzufangen*)
ton0.IN:=TRUE; (*Timer aktivieren*)
ton0(); (*???*)
z:=0; (*Zaehler auf Null setzen*)
a:=0; (*a auf Null setzen, damit er nicht wieder in diese Bedingung rutscht*)
END_IF

IF (z=0) AND (LED=1) THEN (*Zaehler auf eins setzen*)
z:=1;
END_IF;

IF (z=1) AND (LED=0) THEN (*Periode abgeschlossen*)
T1=ton0.ET; (*Dauer übertragen*)
ton0.IN:=FALSE; (*Timer deakt.*)
ton0(); (*???*)
a:=0; (*Bedingung um wieder von vorne anzufangen*)
END_IF


Ich meine eigentlich, das das funktionieren müsste, aber das tut es nicht. Ich glaube ich mache etwas mit den Timern falsch, da diese nicht anspringen.

Dann weiss ich nicht, wie ich mit der Periodendauer weiter rechnen kann, da dieser als Time deklariert ist. ich kann die Frequenz nicht ausrechnen, er streikt. Wie wandel ich die Periodendauer in ein Real Format ?

Vielen dank im voraus.
 

Anhänge

  • frequenz.jpg
    frequenz.jpg
    14,5 KB · Aufrufe: 227
Ich glaube, Du machst es Dir zu schwer.
Um die Frequenz eines Anemometers zu erfassen, brauchst Du doch nur die Impulse je Sekunde zu zählen.
Als erstes brauchst Du also einen Sekunden- Takt:
Var
SecTakt:TON;
Flanke1:F_TRIG;
x:REAL;
rFrequenz:REAL;
xLed:BOOL;
END_VAR
SecTakt(pt:=t#990ms);
SecTakt.IN:=NOT SecTakt.Q;
(*Dann musst Du die Flanke des Impulses auswerten.*)
flanke1(in:=xLed);
(*Jetzt musst Du zählen*)
IF flanke1.Q THEN x:=x+1; END_IF
(*am Ende der Sekunde den Wert speichern und x auf 0 setzen*)
IF SecTakt.Q THEN
rFrequenz:=x;
x:=0;
END_IF
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich glaube, Du machst es Dir zu schwer.
Um die Frequenz eines Anemometers zu erfassen, brauchst Du doch nur die Impulse je Sekunde zu zählen.
Als erstes brauchst Du also einen Sekunden- Takt:
Var
SecTakt:TON;
Flanke1:F_TRIG;
x:REAL;
rFrequenz:REAL;
xLed:BOOL;
END_VAR
SecTakt(pt:=t#990ms);
SecTakt.IN:=NOT SecTakt.Q;
(*Dann musst Du die Flanke des Impulses auswerten.*)
flanke1(in:=xLed);
(*Jetzt musst Du zählen*)
IF flanke1.Q THEN x:=x+1; END_IF
(*am Ende der Sekunde den Wert speichern und x auf 0 setzen*)
IF SecTakt.Q THEN
rFrequenz:=x;
x:=0;
END_IF
Vielen dank für dein ist genial. Mit dieser methode spart man sich die Umrechnung von Time in Real. Aber nur zum anreichern meines Wissens, wie wandelt mein eine TIME Variable in eine REAL Variable?

Deine Lösung muss nur um einen Ounkt erweiter werden. Das setzen eines Startpunktes. Es muss ja bei einer steigenden Flanke beginnen, oder?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich glaube, Du machst es Dir zu schwer.
Um die Frequenz eines Anemometers zu erfassen, brauchst Du doch nur die Impulse je Sekunde zu zählen.
Als erstes brauchst Du also einen Sekunden- Takt:
Var
SecTakt:TON;
Flanke1:F_TRIG;
x:REAL;
rFrequenz:REAL;
xLed:BOOL;
END_VAR
SecTakt(pt:=t#990ms);
SecTakt.IN:=NOT SecTakt.Q;
(*Dann musst Du die Flanke des Impulses auswerten.*)
flanke1(in:=xLed);
(*Jetzt musst Du zählen*)
IF flanke1.Q THEN x:=x+1; END_IF
(*am Ende der Sekunde den Wert speichern und x auf 0 setzen*)
IF SecTakt.Q THEN
rFrequenz:=x;
x:=0;
END_IF

noch eine frage: muss der timer nicht wieder zurückgesetzt werden, weil er nach dem ersten lauf dann aus wäre? also so:

IF (sTakt.Q) THEN ff:=xx; x:=0; sTakt(IN:=FALSE); END_IF;
 
In der Zeile

SecTakt.IN:=NOT SecTakt.Q;

wird der Timer zurück gesetzt, wenn er abgelaufen ist.

wird er dann nicht aktiviert und sobald der Takt von 1s erreicht wird also Q=True ist auf False gesetzt, sodass er ausgeschaltet ist? Verstehe, sobald er false geht, wird der Ausgang Q auch false, sodass er wieder aktiv wird, genial. danke für deine hilfe echt nett von dir. könntest du mir auch bei dem problem http://www.sps-forum.de/codesys-und-iec61131/79291-werte-im-array-verschieben.html helfen?
 
Folgendes Problem. Der Programmcode funktioniert (habe gleichzeitig FREQ_MEASURE laufen, und es liefert in etwa die gleichen Ergebnisse) aber es wird eine falsche Frequenz angezeigt. Die Frequenz zeigt bei codesys z.B. 24 Hz an (obwohl es sehr am schwanken ist 17..25 Hz) aber an einem angeschlossenen Oszilloskop ca 100 Hz. Das Problem ist aber das der Unterschied nicht linear ist sondern bei steigender Windgeschwindigkeit oder sinkinder Windgeschwindigkeit gleich bleibt, sprich immer um die 20 Hz. Am Oszilloskop wird immer der korrekte Wert angezeigt. Liegt auch nicht an einer Beschädigung der Hardware, da ich es bei einer anderen auch probiert habe. Verschiedene Eingänge wurden auch benutzt, immer das gleiche Signal. Woran liegt das? Kann Codesys das nicht so schnell verarbeiten, was ich nicht glaube.
 
Wie sieht Dein Signal aus (Pulslänge, Pausenlänge)?
Wie groß ist die Zykluszeit Deines Programms bzw. wie häufig wird es aufgerufen?
Hat Deine Hardware eventuell auch Hardware-Zählereingänge oder kannst Du Interrupts bei Eingangsflanken nutzen?

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wie sieht Dein Signal aus (Pulslänge, Pausenlänge)?
Wie groß ist die Zykluszeit Deines Programms bzw. wie häufig wird es aufgerufen?
Hat Deine Hardware eventuell auch Hardware-Zählereingänge oder kannst Du Interrupts bei Eingangsflanken nutzen?

Harald

Pulslänge und Pausenlänge sind gleich.
Wo kann ich das nach schauen (Zykluszeit).
Das weiss ich nicht :( haben das hier hhttps://www.rasppishop.de/PiFace-Digital-2-Erweiterungsplatine-/-Modul-fuer-den-Raspberry-Pi-Modell-B-
 
Pulslänge und Pausenlänge sind gleich.
Wenn Du ein Signal von 100Hz zählen willst, dann mußt Du schneller als alle 5ms draufschauen.
In was für einer Task läuft Dein Programm?

Wo kann ich das nach schauen (Zykluszeit).
Das weiss ich nicht. Vielleicht beantwortet das jemand, der sich mit Codesys auskennt. Dazu muß man sich wahrscheinlich den Task-Status online ansehen. Zu "Zykluszeit" sollte es eine Hilfe in Codesys geben.

Harald
 
Wenn Du ein Signal von 100Hz zählen willst, dann mußt Du schneller als alle 5ms draufschauen.
In was für einer Task läuft Dein Programm?


Das weiss ich nicht. Vielleicht beantwortet das jemand, der sich mit Codesys auskennt. Dazu muß man sich wahrscheinlich den Task-Status online ansehen. Zu "Zykluszeit" sollte es eine Hilfe in Codesys geben.

Harald


vielen dank, es lag an der zykluszeit. alles perfekt jetzt
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich würde eine Frequenz nicht über eine Sekunde zählen, sondern direkt die Zeit der Perioden erfassen.
Voraussetzung ist natürlich, dass du dies schnell genug machen kannst.

Code:
VAR
 Signal : BOOL;
 Flanke : R_TRIG;
 Timer : TON;
 Frequenz : REAL;
END_VAR

-----------------------------------------

Flanke(CLK:= Signal);   // Positive Flanke des Signals erzeugen
IF Flanke.Q = TRUE THEN  // Dient zum aktivieren der Flankenerkennung nach langen Pausen
 Timer.IN := TRUE;
END_IF;
Timer(PT:= T#2S);   // Wenn 2S kein Signal kommt, wird frequenz 0 ausgegeben
IF Flanke.Q = TRUE OR
   Timer.Q = TRUE THEN
    IF Timer.ET = T#0S THEN
  Frequenz := 0.0;
 ELSE
  Frequenz := 1000.0 / TO_REAL(Timer.ET);
  Timer(IN:= FALSE);
  Timer(IN:= TRUE); // Neustart des Timers
 END_IF
ELSIF Timer.Q = TRUE THEN
 Frequenz := 0.0;
 Timer(IN:= FALSE);  //Timer zurücksetzen
END_IF

Das Ergebnis der Frequenz kannst du danach noch wie gewünscht filtern, aber so hat man eine genaue Frequenzerfassung.
genauer kannst du es natürlich noch über eine Funktion machen, welche dir die Systemzeit ausgibt, dann benötigst du keinen Timer.
 
Zuletzt bearbeitet:
Zurück
Oben