# Temperaturen loggen mit BK9000 (in Excel)



## olitheis (19 März 2009)

Hallo,
ich würde gerne mit einem BK9000 und 4 x KL3204 (4-Kanal Pt100) zu verschiedenen Zeitpunkten (evtl. Triggerbit) 16 Temperaturen mitschreiben. Am liebsten wäre es mir, wenn ich die Temperaturen (bzw. wahlweise auch andere Variablen) in eine Excel Tabelle schreiben könnte. 
Gibt es hier von TwinCAT aus Möglichkeiten oder eine "externe" Variante wie beim Accon EasyLog bei der S7, der csv Dateien erzeugen kann.

Am liebsten wäre mir natürlich, wenn ich es via TwinCAT direkt in Excel schreiben und immer weiterschieben könnte, also die 16 Werte jedes Mal in eine neue Zeile schreben.

Wäre super, wenn jemand hier eine Lösung vorschlagen kann.
Vielen Dank
Oli


----------



## Neals (19 März 2009)

Du kannst aus der PLC in eine Text Datei schrieben. Beispielsweise FB_FilePuts um eine einzelne Zeile zu schreiben.

Mit Hilfe der Funktionsbausteine schreibst dir eine CSV-Datei welche du in Excel importieren kannst.​


----------



## trinitaucher (19 März 2009)

Prinzipiell:
Wenn du ein PC-basiertes Zielsystem hast (PC oder CX) ist das recht unkompliziert mit Hilfe der Bausteine aus der Bibliothek TcSystem.lib möglich:
http://infosys.beckhoff.com/index.php?content=content/1031/tcplclibsystem/html/tcplclibsys_intro.htm


----------



## olitheis (19 März 2009)

Super, sieht aus, als wäre das genau das Richtige. Aber ich hätte dazu noch eine Bitte:
Könntet ihr mir bitte ein Beispiel geben für TwinCAT, wie ich z.B. die aktuellen Werte von den Variablen (Real) -> *Temp1*, *Temp2*, *Temp3*, *Temp4* immer bei einem TRUE der Triggervariable *log* (Bool) in eine CSV Datei schreiben kann (immer wieder eine neue Zeile).

Ich wäre euch dankbar
Gruß
Oli


----------



## Neals (19 März 2009)

*Beispiel: Dateizugriff aus der SPS*


----------



## olitheis (20 März 2009)

Hallo danke für die Links,
aber ich befürchte, Du mußt mir noch ein wenig unter die Arme greifen. 
Wenn ich das richtig sehe, geht es in dem 'Beispiel' darum, eine Datei von einem Remote System auf den lokalen Rechner zu kopieren. 
Vielleicht könntest Du mir noch ein konkreteres Beispiel geben für:
1. Datei 'logdaten.txt' öffnen (kann aber auch manuell geöffnet werden)
2. dann die Variablen: *Temp1*, *Temp2*, *Temp3*, *Temp4 *bei jeder steigenden
Flanke von der Variable 'log' Zeilenweise (Komma getrennt) diese Datei 
schreiben.
Ich denke dazu kommt entweder:
*FUNCTION_BLOCK FB_FileWrite *








oder:
*FUNCTION_BLOCK FB_FilePuts *






in Frage.
Jedoch komme ich noch nicht so ganz klar. Welcher wäre denn der Richtige FB
und wie muss ich meine Variablen/Daten verpacken (String?/Array?) damit sie in die Datei geschrieben werden können?
Nochmals vielen Dank
Oli


----------



## Neals (20 März 2009)

Naja, benutzt den FB für FileOpen mit dem Append Mode, wie in dem Beispiel und bekommst ein FileHandle zurück. Mit Hilfe dieses FileHandles kannst genauso, wie im Beispiel mit dem Write, mit dem Puts Baustein deine Zeile in die Datei schreiben und diese wieder mit Close schließen...

Bei dem Put Baustein übergibst du einfach einen String, dem wird automatisch das Return angehängt und in die Datei geschrieben.


----------



## olitheis (24 März 2009)

Hallo Neals,
ich habe in der Bibliotheksverwaltung zu meinem PLC Projekt die *TcSystem.lib 11.08.08 10:11:52* geöffnet. Dort unter FILE ACCESS befinden sich sie von Dir genannten FB's (FB_FileOpen, FB_FilePuts, ...). Jetzt habe ich einen neuen Baustein (in FUP) zu meinem Projekt hinzugefügt und dort in das 1. NW den FB_FileOpen eingefügt (s. Anhang). Beim Übersetzten kommen nun haufenweise Fehler die auf diese Bibliothek hinweisen (ADS...Unbekannter Typ...) 
Muss ich noch etwas beachten, wenn ich Bausteine aus dieser neuen Bibliothek verwenden will?
Vielen Dank nochmal 
Oli


----------



## Neals (25 März 2009)

Könnte es sein das du die TcBase.lib rausgeworfen hast? Wenn du die TcSystem einfügst, wird die TcBase normal mit hinzugefügt.


----------



## olitheis (25 März 2009)

Ja, ich hatte die TcBase.lib gelösch. Jetzt übersetzt er ohne Fehler, allerdings scheint es, dass mein Baustein, den ich File_Write genannt habe, der den FB_FileOpen beinhaltet, nicht von der Task berücksichtigt wird, denn er bleibt grau, obwohl ich ihn in MAIN aufrufe. Ich hänge mal mein Projekt mit an, vielleicht kannst Du ja mal reinschauen und mir auch evtl. bei dem String helfen, in den die Variablen geschrieben werden müssen, damit ich sie später im FB_FilePuts einlesen kann. Ich habe zwar in der Online Hilfe von Beckhoff den *FUNCTION DINT_TO_DECSTR : **T_MaxString* gefunden, bin mir aber nicht sicher, wie ich jetzt all die Variablen, die ich in die Datei Wegschreiben möchte, in einen String bekomme.
Nochmals vielen Dank
Oli


----------



## Neals (27 März 2009)

Sorry aber blicke da nicht so recht durch dein Programm durch. Du musst dann auch ein File_Write machen, sonst bringt dir das ganze ja nichts... ausserdem muss auf die bExecute Eingang eine positive Flanke, damit der Baustein aufgerufen wird.


----------



## olitheis (27 März 2009)

Hallo, Da ich ja noch nicht weiß, wie ich meine Variablen in einen String umwandeln muss, hatte ich erst mal mit dem FileOpen begonnen, und wollte das so testen. Aber es scheitert ja schon daran, dass ich mein Baustein ja gar nicht läuft (bleibt grau). Muss ich den FileWrite bzw. FileClose grundsätzlich immer dabei haben damit es funktioniert? Es wäre echt supernett, wenn Du evtl. mal das Programm so abändern könntest, dass ich mit der pos. Flanke von IN_1 meine Datei öffnen kann, mit IN_2 dann die vier Temperaturen (im String?) in die Datei schreiben kann und mit IN_3 dann die Datei wieder schliessen kann. 
Wird die Datei eigentlich richtig geöffnet, oder nur im Hintergrund beschrieben, also sieht man, dass die Datei geöffnet wurde?
Vielen Dank
Oli


----------



## olitheis (31 März 2009)

Hallo, 
ich habe das mit dem FilePuts leider noch nicht hinbekommen. Momentan hängt es daran, dass ich die Variablen nicht in einen String gewandelt bekommen. Ich habe jetzt einen FB_FORMATSTRING gefunden:




damit können bis zu 10 Argumente in einen String formatiert werden. Jetzt stellt sich mir die nächste Frage: wie bekomme ich meine Variablen (Real) zu diesen Argumenten gewandelt? Es gibt eine FUNCTION F_REAL




(Eine Hilfsfunktion, die in einer Struktur Informationen zu einer REAL-Variablen zurückliefert.)
allerdings weiß ich auch nicht, wie ich diese "Funktion" verwenden kann, wenn es denn überhaupt der richtige Weg ist???
Wäre super, wenn ihr mir nochmal weiterhelfen könntet.
Vielen Dank
Oli


----------



## Cerberus (31 März 2009)

In ST gibt es die Funktion "REAL_TO_STRING". Ergo muss es sowas ja wohl auch als Baustein in FUP geben.


----------



## olitheis (31 März 2009)

OK, wenn das ginge könnte ich eine einzige Realzahl in einen String umwandeln, wie könnte ich dann aber z.B. 20 Variablen in einen String wandeln?
Danke
Oli


----------



## Cerberus (31 März 2009)

Wenn die Umwandlung von Real nach String funzt ist der Rest nur noch eine Kleinigkeit:


```
String := '';
String := CONCAT(String, REAL_TO_STRING(Var1));
String := CONCAT(String, REAL_TO_STRING(Var2));
String := CONCAT(String, REAL_TO_STRING(Var3));
String := CONCAT(String, REAL_TO_STRING(Var4));
String := CONCAT(String, REAL_TO_STRING(Var5));
String := CONCAT(String, REAL_TO_STRING(Var6));
String := CONCAT(String, REAL_TO_STRING(Var7));
String := CONCAT(String, REAL_TO_STRING(Var8));
String := CONCAT(String, REAL_TO_STRING(Var9));
String := CONCAT(String, REAL_TO_STRING(Var10));
String := CONCAT(String, REAL_TO_STRING(Var11));
String := CONCAT(String, REAL_TO_STRING(Var12));
String := CONCAT(String, REAL_TO_STRING(Var13));
String := CONCAT(String, REAL_TO_STRING(Var14));
String := CONCAT(String, REAL_TO_STRING(Var15));
String := CONCAT(String, REAL_TO_STRING(Var16));
String := CONCAT(String, REAL_TO_STRING(Var17));
String := CONCAT(String, REAL_TO_STRING(Var18));
String := CONCAT(String, REAL_TO_STRING(Var19));
String := CONCAT(String, REAL_TO_STRING(Var20));
```


----------



## Cerberus (31 März 2009)

Habe gerade etwas in FUP rumgespielt. Den Baustein REAL_TO_STRING gibt es auch in FUP. Dazu fügst du einfach einen neuen Baustein ein und beschreibst diesen mit "REAL_TO_STRING". Danach kannst die einzelnen Strings, die du aus deinen Reals gewonnen hast mit CONCAT zusammenfügen. Hab dir im Anhang mal ein Beispiel für 2 Variablen.


----------



## olitheis (31 März 2009)

OK, prima.
Also mit dem CONCAT und zwei String-Variablen funktioniert es.
Aber wie Du das mit den 20 Variablen meinst, kann ich gerade nicht nachvollziehen. Willst Du damit einen neuen FB erstellen mit 20 Real Variablen am Eingang und als Ausgang eine String-Variable?
Kann ich da einen neuen Baustein erstellen (FB) und das einfach so runtertippen? Könntest Du dazu vielleicht noch ein Beispiel mit anhängen? 

Und dann noch eine Frage zum FilePuts: wie kann ich erreichen, dass meine Variablen entweder Kommagetrennt o.ä. geschrieben werden und dass danach ein return mitgeschickt wird, so dass beim nächsten Mal in eine neue Zeile geschrieben wird?
Vielen vielen Dank
Oli


----------



## Cerberus (31 März 2009)

Also ich hab dir mal ein Beispiel im Anhang. Was mir allerdings aufgefallen ist: Ein normaler String kann maximal 80 Zeichen lang sein. Das macht Probleme. Du müsstest also immer nur 3-4 Variablen zu einem String zusammenfügen. und diese Strings dann nacheinander in die Datei schreiben.

Die Trennzeichen zwischen den einzelnen Werten bekommst du hin, indem du auch wieder mit CONCAT das Trennzeichen zum String hinzufügst, nachdem ein neuer Wert hinzugefügt wurde. Das gleiche mit dem Zeilenumbruch. Dazu fügst du einfach "$n" hinzu.
Kannst beides aber auch im Beispiel nachschauen.


----------



## Cerberus (31 März 2009)

Nachtrag zu den Strings:

Habe gerade im InfoSystem von TwinCAT gesehen, dass man Strings auch eine Zeichenlänge vorgeben kann. Allerdings ist 255 die maximale Zeichenlänge.

Ersetze dafür einfach in der Deklaration "STRING" durch "STRING(255)".


----------



## trinitaucher (31 März 2009)

man kann Strings maximal als STRING(255) deklarieren, also mit bis zu 255 Zeichen.

edit:
War der Cerberus mal wieder schneller


----------



## Cerberus (31 März 2009)

@olitheis:

Hab dir jetzt hier mal die überarbeitete Version des Beispiels mit den langen Strings.


----------



## olitheis (31 März 2009)

Ich kann's gerade nicht testen, aber ich denke, ich habs verstanden:
1. du nimmst also die Variable Var1 und wandelst sie in string1
2. dann fügst Du min CONCAT ein Semikolon ';' zu string1 hinzu
(kurze Frage: wann verwendet man diese einfachen Anführungszeichen ' ' immer?)
3. dann fügst du Var3 zu string 1 hinzu
4. wieder ein ';'
usw.
zum Schluss (nach 20 Variablen) hängst Du ebenfalls mit CONCAT ein '$n' an, um in die nächste Zeile im Textfile zu springen

Und ich darf in string1 max. 80 Zeichen "verpacken", d.h., wenn ich Temperaturen habe unter 100°C dann sollten es nicht mehr wie 16 Variablen sein mit je 5 Zeichen (Beispiel: 18.56°C) oder muss ich die Semikolon auch dazuzählen?
Könnte man hier auch einen T_MaxString verwenden? 
_edit: ... ihr wart hier schneller mit der Antwort als ich mit der Frage..._

Nochmals vielen Dank
Oli


----------



## Cerberus (31 März 2009)

Zu den Anführungszeichen. Ich würde immer die einfachen benutzen. Würde behaupten, dass TwinCAT die doppelten überhaupt nicht nimmt.

Zu 3)
Du meintest Var2 oder?

Zum String:

Der String darf maximal 255 Zeichen lang sein. Dazu musst du allerdings die max. Länge bei der Deklaration angeben.
Zu diesen 255 Zeichen zählen alle. Auch ;, ,, °, C, $, n. Wenn du also als Beispiel Werte mit folgendem Format hast "18.56°C", dann hast du bei 20 Werten insgesamt 140 Zeichen für die Werte, 19 Zeichen für die ";" als Trennzeichen und 2 Zeichen für das Return "$n", also zusammen 161 Zeichen. Du hättest also noch Platz für 94 Zeichen. Du könntest also deine Werte noch um 4 Zeichen erweitern.


----------



## olitheis (31 März 2009)

Mir war/ist nicht so ganz klar, wann man diese ' ' überhaupt verwendet. Hier z.B.:






sind diese *' '* bei sNetID, oder hier bei *'*Put this line*!$L'*? 

und ja, bei 3. meinte ich Var2


----------



## Cerberus (31 März 2009)

Die ' bedeuten den Anfang oder das Ende eines Strings. In den beiden von dir genannten Beispielen werden dem FB einfach zwei Strings übergeben, die nicht als Variable deklariert sind.

Edit:
Du könntest natürlich auch zwei String-Variablen mit dem selben Inhalt deklarieren und diese dann dem FB übergeben.


----------



## olitheis (31 März 2009)

Soweit alles prima!
Nur noch eine Kleinigkeit: die Real OUT_TEMP1...20 Variablen müssten auf 2 Stellen hinter dem Komma gerundet werden. Bei Schreiben werden teilweise 14 Stellen hinter dem Komma angezeigt. Ich hänge mein Testprojekt mal mit an. Das sollte wahrscheinlich am besten in meinem TEMP_FB gemacht werden, oder?
Vielen Dank
edit: wobei nur im String die vielen Stellen hinterm Komma auftauchen und nicht in der REAL Zahl


----------



## Cerberus (1 April 2009)

Hab dir im Anhang mal ne Lib, die du bei dir einbinden kannst. Darin enthalten ist der Baustein, um die 20 Werte zu einem String zusammenzufügen. Gleichzeitig wird aber auch jeder Wert, der mehr als 2 Nachkommstellen besitzt auf die 2. Stelle gerundet.
Kannst dir ja wenn du willst auch mal den Code des Bausteins anschauen. Dazu gehst du einfach in PLC Control, dann auf Öffnen und wählst als Dateityp "Bibliothek".


----------



## olitheis (1 April 2009)

Hallo Cerberus,
vielen Dank für die Lib, das ist echt super!
Ich habe den Baustein mal verwendet, dabei sieht es so aus, als würde auf 3 Stellen hinterm Komma gerundet: aus 3276.699951... wird 3276.610(?) Im screenshot kannst Du es sehen. 
Das soll natürlich keine Kritik sein ;-), wollte es nur bemerken.
Nochmals vielen Dank kfür Deine Hilfe!
Oli


----------



## Cerberus (1 April 2009)

Es wird eigentlich immer noch auf zwei Stellen gerundet. Nur ist jetzt die zweite Stelle eine zehn, da sie vorher neun war und durch die dritte Stelle um eins erhöht wurde. Werd's mal kurz verbessern.


----------



## Cerberus (1 April 2009)

Ist doch eine größere Angelegenheit als ich dachte. Wird noch ne Weile dauern. Hoff aber dass es spätestens bis morgen früh fertig ist.


----------



## Cerberus (1 April 2009)

So jetzt aber. Die Rundung funktioniert jetzt für Zahlen bis 1000. Teste es aber lieber noch einmal bevor du dich wirklich darauf verlässt.


----------



## McNugget (2 Dezember 2009)

Hallo Cerberus,

habe diesen Thread in der Suche gefunden, und möchte ihn nun noch einmal aufgreifen, da ich das gleiche Problem habe.

Bei negativen Werten hatte ich in der Lib die Du am 01.04.2009 09:40 angehängt hattest, das Problem, das negative Zahlen um 0 herum als exponentielle Zahlen im String erschienen, obwohl ich die Rundung bereits vorher in den eingegebenen Real-Werten vorgenommen hatte.

Das mit dem Runden scheint aber schon nicht zu funktionieren. Wie runde ich so, dass aus -0,0045 einfach nur -0,00 wird? und nicht 0.E000

Bei der lib, die Du am 01.04.2009 16:13 angehängt hast, scheint irgendwas nicht so gut zu funktionieren. (Siehe Anhang.)


Leider ist der Code in der Lib die Du geschribeen hast nicht auskommentiert, so dass ich überhaupt nicht nachvollziehen kann, was Du tust.

Kannst Du mir dazu mal etwas mehr erzählen?

Lernen will.


----------



## Cerberus (2 Dezember 2009)

Also erstmal sorry dass cih die Lib nicht kommentiert hab. Muss ich echt noch ändern.

Ich werds mir mal anschauen und dir dann hoffentlich weiterhelfen können.


----------



## McNugget (2 Dezember 2009)

Mann bist Du schnell...

Wohnst Du hier im Forum??



Das wäre total klasse. Denn die Lib an sich ist ne super Sache.


Ich muss allerdings ca. 40 Werte plus Timestamp ausgeben.

Das werde ich aber wegen der 255-Zeichen-Beschränkung in mehreren Bausteinen abhandeln.


----------



## Cerberus (2 Dezember 2009)

McNugget schrieb:


> Mann bist Du schnell...
> 
> Wohnst Du hier im Forum??


 
Hättest wohl gern! 

Ne ich häng zur Zeit nur ständig im Netz und dann kann ich auch online sein.


----------



## Fx64 (2 Dezember 2009)

Hallo,

Strings kann man sehr wohl größer als 255 deklarieren, nur die klassischen Stringfunktionen arbeiten nur bis 255. Denkbar wäre aber ein String(1000) der per memcpy zusammengesetzt wird.

Viele Grüße


----------



## Cerberus (2 Dezember 2009)

Fx64 schrieb:


> Hallo,
> 
> Strings kann man sehr wohl größer als 255 deklarieren, nur die klassischen Stringfunktionen arbeiten nur bis 255. Denkbar wäre aber ein String(1000) der per memcpy zusammengesetzt wird.
> 
> Viele Grüße


 
TwinCAT lässt nur Strings mit einer maximalen Länge von 255 Zeichen zu.


----------



## Cerberus (2 Dezember 2009)

@ MCNugget

Also jetzt mal folgende Diagnose auf die Schnelle:

Wenn ich z.B. -0.0045 eingebe, dann kommt bei mir als Ergebnis -4.5 raus. Laut deinem Pdf bei dir auch. Das Ganze kommt daher, dass TwinCAT intern aus dem -0.0045 ein -4.5e-003 macht. Um das in der Lib noch abzufangen müsste ich mich mal noch ein paar Stunden dransetzen. Kann dir leider aber nicht versprechen dass ich dazu diese Woche noch komme. Versuche es aber sobals als möglich zu erledigen. Falls du nichts mehr von mir hören solltest, mich einfach nochmal dran erinnern.

Gruß Cerberus


----------



## Fx64 (2 Dezember 2009)

Hallo Cerberus,

nein, bein TwinCAT kannst Du auch Strings größer als 255 deklarieren.

Viele Grüße


----------



## Cerberus (2 Dezember 2009)

Fx64 schrieb:


> Hallo Cerberus,
> 
> nein, bein TwinCAT kannst Du auch Strings größer als 255 deklarieren.
> 
> Viele Grüße


 
Ja du hast recht. Ich habs grad selber ausprobiert. Bin vorhin vom InformationSystem ausgegangen. Darin steht:



> Eine Variable vom Typ STRING kann eine beliebige Zeichenkette aufnehmen. Die Größenangabe zur Speicherplatzreservierung bei der Deklaration bezieht sich auf Zeichen und kann in runden oder eckigen Klammern erfolgen. Ist keine Größe *(1 bis 255)* angegeben, so werden standardmäßig 80 Zeichen angenommen. Strings sind alle nullterminiert. D.h. das letzte Zeichen eines Strings ist immer Null.


 
Quelle


----------



## Fx64 (2 Dezember 2009)

Hallo, 

ich weiß, aber manchmal geht auch mehr als in der Dokumentation steht ;-).

Viele Grüße


----------



## Cerberus (2 Dezember 2009)

Fx64 schrieb:


> Hallo,
> 
> ich weiß, aber manchmal geht auch mehr als in der Dokumentation steht ;-).
> 
> Viele Grüße


 
Gut zu wissen!


----------



## McNugget (2 Dezember 2009)

Hallo Cerberus.

Ich möchte Dir nicht zumuten, Dir die Stunden meinetwegen um die Ohren zu schlagen.

Parallel habe ich im Oscat-Forum nachgefragt.

Hugo war schnell und hat gleich die Funktion Real_to_strf genannt.

Die sieht genau so aus, wie das, was ich will.

Wenn man die in den Baustein integriert , wäre es alles, was man braucht.

Oder kannst Du mir zeigen, wie ich einen Baustein mache, mit dem ich Strings beliebeig aneinanderreihen kann?

Es würde aber sicher schon reichen, wenn die Aktionen in der Lib auskommentiert sind.

Denn sonst kann ich ja nichts mehr lernen. ;-)


----------



## Cerberus (3 Dezember 2009)

@McNugget

Also ich hab in der Lib jetzt mal den Part für die erste Variable kommentiert. Für die anderen Variablen läuft es genauso. Hoffe dir hilft das weiter.

Solltest du dennoch weitere Fragen haben, kannst du dich gerne nochmal an mich wenden.


----------

