Beschleunigunssensor liefert keine eindeutigen Werte

Gluttony

Level-1
Beiträge
13
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

ich habe einen Beschleunigungssensor, welcher einen Messwertbereich von +-50 g (Erdbeschleunigung) erfassen kann. Dieser ist an eine Beckhoffklemme KS3001 angeschlossen und die SPS ist eine CX1010.

Ich habe den Sensor über eine Teststrecke in einem Behälter fahren lassen und Messwerte aufgenommen und mit Excel visualisiert. Siehe Dateianhang Zwischenablage.

Leider ergibt sich bei jeder Messfahrt eine komplett neue Grafik mit anderen Beschleunigungsspitzen. Eigentlich wollte ich anhand der Beschleunigungen Fehler/zu harte Stöße in der Anlage erkennen. Beispielsweise wenn eine Förderrolle fehlt und Behälter sehr unsanft durchgefördert wird.

Nach langem Überlegen habe ich mir gedacht, dass vielleicht ein Fehler in der Programmierung vorliegt. Programmierung als code.txt siehe Anhang.

In der Programmierung habe ich eine If-Schleife(i = 1 bis 5) die hochzählt und die Erfassten Sensorwerte in ein Array (Array [1] bis [5]) schreibt. Anschließend wird das Array in String umgewandelt und gespeichert. Daraufhin wird die If-Schleife wieder aufgerufen usw...
Ist an dieser Vorgehensweise etwas falsch?

Ich weiß, dass das ein bisschen viel ist, aber wenn jemand eine Idee hat, wäre ich sehr dankbar.

Gruß Gluttony
 

Anhänge

  • Zwischenablage01.gif
    Zwischenablage01.gif
    44,2 KB · Aufrufe: 28
  • Code.txt
    8,5 KB · Aufrufe: 22
Hallo,
ich habe da ein Verständnisproblem mit deinem Vorhaben.
In welchem Verhältnis steht das dargestellte Diagramm zu der Aussage, dass du (nur) 5 Werte aufzeichnest ?
In welchem Intervall liesst du den Sensor ein ?
Da ich nicht so der Beckhoff-Mann bin - ist die genannte Klemme die Richtige für den Sensor (wegen des Auflösungsbereichs) ?

Ich würde da in etwa so machen :
Während der gesammten Aufzeichnungszeit in einem sehr kurzen Intervall (<= 2 ms) den Sensor abfragen und in ein entsprechend groß dimensioniertes Array einlesen. Wie lange dauert dein Mess-Vorgang ?

Gruß
Larry
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Man kann anhand der Grafik nichts sehen, denn es fehlt die Skalierung.

50g ist zuviel. Du wirst damit wohl in erster linie das Sensorauschen messen. Beschleunigungen in unserer Welt spielen sich in der Regel bis 1g ab.

Bei einer guten Messung auf einem Wagen, solltest du am Anfang der Fahrt eine Art Rechteck haben und natürlich das selbe mit anderem Vorszeichen auch am Ende der Fahrt.
 
Das mit den 5 Werten habe ich so gemacht, damit die Werte vom Sensor ins Array geschrieben werden und dann die Werte des Arrays 1-5 in einen String geschrieben werden, der dann in eine TXT-Datei gespeichert wird.

Damit das ganze fortläuft, rufe ich die If-Schleife erneut auf usw.
Der Zeitraum für eine ganze Messung soll später bis zu einer Stunde gehen.
---
Die genannte KS3001 wurde mir von Beckhoff selbst empfohlen, sie weist zwar nicht beste Auflösung auf, sollte aber ausreichen.
---

Das Sensorrauschen ist ziemlich gering, dass die Nulllinie nicht bei Null liegt, geht auf das Offset des Beschleunigungssensors zurück.
Bei den kürzeren Messfahrte oder beim Reinzoomen in meine Excel-Tablle sind die Anfahr und Abbremsbeschleunigungs-Rechtecke eindeutig zu erkennen.
---
10 g sind locker drin, in der Grafik die ich angehängt habe, haben wir sogar bis über 40 g Beschleunigungsspitzen.



Ich glaube mitlerweile, dass ein Fehler mit der If-Schleife zusammenhängen kann, aber ich habe da nicht genung Programmierkenntnisse um das zu beurteilen.
Muss die If-Schleife für das Einlesen der Werte in Array höher gestellt werden, also nicht nur 5 sondern vielleicht 50 bevor "gespeichert" wird.

Gruß gluttony
 

Anhänge

  • vertikale_beschleunigung.jpg
    vertikale_beschleunigung.jpg
    251,6 KB · Aufrufe: 15
Zuletzt bearbeitet:
Ich glaube mitlerweile, dass ein Fehler mit der If-Schleife zusammenhängen kann, aber ich habe da nicht genung Programmierkenntnisse um das zu beurteilen.
Muss die If-Schleife für das Einlesen der Werte in Array höher gestellt werden, also nicht nur 5 sondern vielleicht 50 bevor "gespeichert" wird.

Das Schreiben der Daten kann durchaus mehr als einen Programmzyklus dauern. So wie es jetzt programmiert ist, wird aber weiterhin jeden Zyklus lang die Variable "Datensatz" neu beschrieben, d.h. auch während der Inhalt in die Textdatei geschrieben wird.

Ich würde es folgendermaßen machen.
Einen ausreichend großen Puffer anlegen der die Zeit überbrückt die für das Schreiben der Datei benötigt wird.
Also z.B. 1 Sekunde lang im Puffer1 halten, wenn Puffer1 voll, evtl. in einem Puffer2 umkopieren.

Dann kann quasi parallel die Messwertaufzeichnung in den Puffer1 laufen, und im anderen Schritt dazu parallel das Erstellen der Textdatei mit den Daten aus Puffer2.
 
In welchem Intervall liesst du den Sensor ein ?
Der Sensor wird immer eingelesen, ich glaub ich verstehe die Frage nicht richtig.

Mein Programmcode in ganz kurz:

IF i<5 THEN
i:=i+1;
Beschleunigung := INT_TO_REAL(Beschleunigungssensor_1)
WertinArray:= Beschleunigung;
IF i=5 THEN
i:=0;
END_IF


Datensatz := REAL_TO_STRING(WertinArray[1]); + alle weiteren Werte in Array 2-5
und deren Speicherung als "Datensatz" in Datei.
--------
Nach Thomas seiner Aussage, würde ich sagen, dass meine Messwerte teilweise überschrieben werden, während sie gespeichert werden.

Ich dachte, dass die SPS immer erst einmal durchläuft, also wird WertinArray[1] erst wieder überschrieben, wenn es auch gespeichert wurde. Warum sollte die If-Schleife direkt neu starten, bevor die Werte des Arrays in den "Datensatz" kopiert wurden?

Gruß von einem verwirrten Gluttony
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich dachte, dass die SPS immer erst einmal durchläuft, also wird WertinArray[1] erst wieder überschrieben, wenn es auch gespeichert wurde. Warum sollte die If-Schleife direkt neu starten, bevor die Werte des Arrays in den "Datensatz" kopiert wurden?
Was ist eine If-Schleife?

Bei dir wird das Array WertinArray jeden Zyklus mit einem neuen Wert versorgt.
Der String Datensatz enthält ebenfalls in jedem Zyklus die aktuellen Werte aus dem Array, auch wenn diese gar nicht zum Schreiben benötigt werden.

Wenn 5 Werte in dem Array sind triggerst du den Schreibvorgang an.
Dieses hast du ja in einer Schrittkette eingebaut, mit FB_FileOpen, FB_FileWrite und FB_FileClose.
Diese Funktionen brauchen aber garantiert länger als einen Zyklus bis sie fertig sind. Darum fragst du ja als Weiterschaltbedingung auch die Busy-Flags der Funktionen ab.

Mal angenommen fbOpenLogFile() braucht 10 Zyklen (ich weiß nicht wie lange es dauert aber bestimmt mehr als 1) gehen dir an dieser Stelle schonmal 10-arraysize (also 5) = 5 Messwerte verloren.
Die Dauer der anderen Aufrufe von fbWriteLogFile() und fbCloseLogFile() kommen dann noch obendrauf.

Wie oben schon von mir geschrieben, brauchst du einen entsprechend großen Puffer der diese Zeiten überbrückt. Und während fbWriteLogFile() aufgerufen wird, dürfen die Werte die geschrieben werden nicht verändert werden, sonst ist der zeitliche Ablauf in der Datei nicht mehr gegeben, und du hast so wie du es jetzt hast bei jedem Logfile ein komplett anderes Bild.

Die CX Steuerung hat doch Speicher satt. Ich würde erstmal ordentlich im Ram puffern und z.B. nach 100 Werten oder im festen Zeitraster die Datei schreiben.
 
Danke für die ausfühliche Erklärung!

Ich würde erstmal ordentlich im Ram puffern und z.B. nach 100 Werten oder im festen Zeitraster die Datei schreiben

Okay, also hilft es auch nichts, wenn ich mein Array erweitern würde von 5 auf 50, da die Werte während des letztendlichen Schreibens einfach schon überschrieben/aktualisiert wurden.

Also muss ich die Werte im Array im Ram zwischenspeichern, Puffern, wie du gesagt hast,...
aber ich weis nicht wie und das ist ziemlich bitter. Gib mir bitte einen Denkanstoss.
 
Synthetische Daten

In einem Fall wie diesem, wo nicht klar ist, was überhaupt passiert, sollte man mit synthetischen Daten hier eine var mit Namen count arbeiten.

Z.B:

IF (count > 20000) THEN
count := 0;
END_IF

Wert := count;
count := count +1;

IF (i >= 5) THEN
i := 1;
ELSE
i := i +1;
END_IF

Dann sieht man sehr schnell, wenn Zyklen überschrieben werden etc. Count hat hier die Möglichkeit über 20.000 Zyklen zu laufen, das sollte reichen, sonst Datentyp DINT nehmen oder so.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich würde das Ganze in zwei Funktionsbausteine zerlegen:

1) FB für die Handhabung des Speichers (Array)
2) FB der die Arraydaten in eine Datei schreibt

Programm 1) macht nichts anderes als deinen Messwert in ein Array zu speichern.
Dieser Baustein macht eine Meldung wenn das Array voll ist (oder Zeitsignal oder sonstiger Trigger wie Messfahrt Ende).
Diese Meldung nimmt Programm 2) auf und schreibt die aktuelle Anzahl der Daten im Array in die Datei.
2) muss dafür sorgen dass es das Array in einem Zyklus entweder abgearbeitet hat, oder für die Bearbeitungszeit im Ram zwischenspeichert.
Programm 1) kann dann direkt im nächsten Zyklus anfangen das Array von 0 an wieder vollzuschreiben.
 
Ich würde das Ganze in zwei Funktionsbausteine zerlegen:

1) FB für die Handhabung des Speichers (Array)
2) FB der die Arraydaten in eine Datei schreibt

Programm 1) macht nichts anderes als deinen Messwert in ein Array zu speichern.
Dieser Baustein macht eine Meldung wenn das Array voll ist (oder Zeitsignal oder sonstiger Trigger wie Messfahrt Ende).
Diese Meldung nimmt Programm 2) auf und schreibt die aktuelle Anzahl der Daten im Array in die Datei.
2) muss dafür sorgen dass es das Array in einem Zyklus entweder abgearbeitet hat, oder für die Bearbeitungszeit im Ram zwischenspeichert.
Programm 1) kann dann direkt im nächsten Zyklus anfangen das Array von 0 an wieder vollzuschreiben.

ja genau, ich würde das auch so probieren,
ausserdem, bei extrem kurzen Abtastraten, würde ich mir überlegen ob
jeder Wert geschrieben werden muss oder nur wenn er z.B. mehr als x Prozent
vom Vorgänger unterschiedlich ist...

pseudo-code

Code:
if (StartMessung = 0) then
 old_beschl = 0
else
 if (Beschl <> 0) then
  prozent = abs(100 - 100 * old_beschl / Beschl)
  if (prozent > 10) then
   ringbuffer.add(wSecond, Beschl, ZSchiene_Sensor_1, ZSchiene_Sensor_2, Temperatursensor_1, Temperatursensor_2, sonst_noch_was)
   old_beschl = Beschl
  endif
 endif  
endif
if (ringbuffer.fuellstand > 0) then
 ringbuffer.getNext
 make string
 write to file
else if (StartMessung = 0) then
 close file
endif
 
Das mit den 2 Arrays ist das einfachste meiner Meinung nach:

du machst 2 exakt identische Arrays: (genug gross - abhängig vom Zielsystem)

arrBuffer <- hier schreibst du wie bisher die Werte rein
arrSpeichern <- hier kopierst du nach dem schreiben vom letzen Wert des arrBuffer die Werte rein.

Code:
IF i = 1000 THEN
arrSpeichern := arrBuffer;
i:=0;
//Jetzt speichern anstossen

Und speichere doch die Werte als INT - so brauchen sie viel weniger Speicher, umwandlen kannst du dann beim Schreiben!
 
hallo,

man könnte auch z.B. 1000 Variabeln in ein Array nach und nach schreiben (pro Zyklus +1) und dann:

bei 1001 den Counter auf 0 setzten
das Array in ein anderes Array kopieren
und dann dieses zweite Array parallel zum aufzeichnen als file schreiben.

Somit hat die SPS 1000 Zyklen zeit die Daten zu schreiben, oder???

MfG CAS
 
Zurück
Oben