11-18-2012 11:02 AM
Hallo DIAdem-Gemeinde,
ich befinde mich leider in der glücklichen Position, ein altes DIAdem Script, welches unter Diadem9.0 geschrieben wurde, in Diadem2012 anzupassen.
Im Moment macht mir folgendes Problem Sorgen:
Vor jeder Berechnung werden die aktuellen Kanalnamen in ein array gespeichert mit name(i)= ChnName(i). Wenn ich das mit allen 501 Kanälen machen möchte, geht das ganze nur bis i = 450. Gibt es eine max. Begrenzung der Einträge eines arrays in DIAdem bzw. vbs?
Wenn ich nun versuche das ganze anders sinnvoll zu lösen, verstricke ich mich nur in mehr Fehler... Das ganze wir dazu gemacht, um nach der jeweiligen Berechnungsroutine die Kanalnamen wieder zurück zu kopieren. Sonst steht da nur noch Copy1 bis... und MatScalMul1 bis....
Gibt es dafür eine sinnvolle Alternative? Und wie greife ich generell auf Kanäle zu? Wenn ich mit den alten Befehlen wie ChnName(i) z.b. darauf zugreife, benutzt DIAdem dann den Index oder die Kanalnummer?
Vielen vielen Dank schonmal im Voraus,
ich hoffe ich finde eine geeignete Lösung, langsam geht mir die Puste aus
Grüße
11-19-2012 06:13 AM
Hallo Hummel3,
ich habe in DIAdem 2012 ein kleines Skript geschrieben das 600 Kanäle erzeugt, die Namen in ein Array „name(i)“ rein schreibt und anschließend in zwei neue Kanalgruppen neue Kanäle mit diesen gespeicherten Namen erzeugt. Ich hatte damit keine Probleme. Vielleicht hast du den Array nicht genügend groß initialisiert? Ansonsten wüsste ich nicht woran es liegen könnte. Vielleicht kannst du ja in dem Fall ein kleines Beispiel hier posten.
Ich habe mir auch den ChnName-Befehl und in wie weit Kanalnummern oder Indizes betrachtet werden angeschaut. Wenn man einfach nur ChnName(i) nutzt ist i die Kanalnummer. Bei ChnName("[1]/["&i&"]") ist i der Index des Kanals in der Kanalgruppe mit Index 1.
Ich habe mein Beispielskript angehangen. Ich hoffe es hilft dir weiter.
11-20-2012 02:27 AM
Hallo Lorenz-Mie,
vielen Dank für deine Hilfe. Ich hab mit Hilfe deines Skriptes, mein eigenes noch einmal nachvollzogen und bemerkt, dass ich eines von den beiden arrays nicht
genügend groß initialisiert hatte... nun klappt es bestens, vielen Dank!
Die andere Frage bleibt jedoch:
Ist es möglich die Kanalnamenüberschreibung beim Kopieren und bei MatScal Operationen auszustellen? Im Moment speichere ich jedes mal vor einer Berechnungsroutine alle Kanalnamen und speichere sie danach wieder zurück, was sicherlich nicht optimal ist...
Vielen Dank.
Grüße
11-20-2012 08:17 AM
Hallo Hummel3
Die Funktion MatScalMul erlaubt ein "InPlace" arbeiten bei dem kein neuer Kanal angelegt wird sondern die daten im existierenden Kanal multipliziert werden. Hilf das weiter ?
Was das Kopieren betrifft : Wenn ein Kanal kopiert wird, muss der neue Kanal einen anderen Namen wie der Ausgangskanal erhalten. Ansonsten könnte man die beiden Kanäle nicht unterscheiden.
Mir ist der Ablauf im Skript nicht wirklich klar. Wäre es möglich den relevanten Abschnitt zu posten, so dass man sich den Ablauf besser vorstellen kann ?
11-20-2012 08:29 AM
Hallo,
beim ChnCopy Befehl (wenn du den meinst) kann man einen Namen direkt angeben. Bei den MatScal-Operationen habe ich bisher auch keine Lösung gefunden. Entweder man lässt sich den Quellkanal überschreiben oder es wird ein neuer Kanal mit Namen MatScalMulZ1 usw erzeugt.
So ganz genau kann ich mir auch noch nicht vorstellen was bei dir die einzelnen Schritte bewirken sollen.
Ich habe noch ein kleines Skript geschrieben, was jetzt die Kanäle der ersten Kanalgruppe in eine neue Kanalgruppe rein kopiert (bei Beibehaltung der Kanalnamen ohne zusätzlichem Array) und anschließend ein MatScalMul auf alle Kanäle anwendet.
Vielleicht hilft es dir weiter?
Raphael
11-20-2012 02:49 PM - edited 11-20-2012 02:49 PM
Hallo ihr beiden,
also vielleicht kann ich ein wenig mehr über das Skript erzählen. Weil es an die 5500 Zeilen hat und ich nicht weiß ob ich es der "Öffentlichkeit" zugänglich machen darf, mal ein paar Erklärungen. Im Prinzip besteht das Skript aus einzelnen Subroutinen, die die gewonnenen Messdaten erst einlesen und dann sukzessive weiter verarbeiten (Nullpunktverschiebung, Umrechnung in physikalische Einheiten, andere Berechnungen mit Hilfe einer DLL und darin befindlichen c++ Routinen).
Da das vbs Skript unter Diadem 9 von (leider wenig begabten) Programmierern erschaffen wurde, gibt es bei meiner "Implementierung" in Diadem 2012 einige Probleme.
Mit das größte Problem ist jedoch, dass die Übergabeparameter für die dll bzw. die c++ Routinen in die Kanäle 470-500 geschrieben werden. Die dll(gpiexl) ist so (schlecht) programmiert, dass sie sich aus Diadem die Werte (Kanäle 470-500) nimmt und die Ergebnisse der Berechnung wiederrum in Kanäle zwischen 470 und 500 schreibt. Nun konnte man im alten Diadem ohne dynamische Kanalverwaltung noch auf Kanäle mit beliebig großem Index zugreifen, diese wurden direkt erstellt. Im neuen Diadem kann man leider keinen Kanal 400 erstellen wenn die bisherigen Kanäle nur bis z.B. 45 gehen. Daher habe ich zuerst 500 Kanäle mit jeweils 32768 1sen erstellen lassen in die dann die Werte eingelesen werden (zumindest erstmal in die ersten 58).
Im alten Skript wird vor jeder Operation der Name und der Typ des Kanals folgendermaßen gespeichert:
for i=1 to GlobUsedChn name(i)= ChnName(i) sondentyp(i) = CC(i) next
und nachher wieder andersherum zurück gelesen.
Alle Operationen wie Messwerte verkürzen, einzelne Abschnitte ausschneiden wurden bis jetzt auch immer für jeden Kanal ausgeführt. Nun habe ich das Skript soweit angepasst, dass es vor jeder Berechnung die Kanalnamen wie oben angegeben speichert und nachher zurück liest. Problematisch wird dies jedoch in den Subroutinen wo eine Zwischengruppe erstellt wird, in der die Werte der Berechnung abgelegt werden. Im alten Diadem 9.0 konnte man auf die jeweiligen Kanäle im aktiven Datenset noch mit (i) zugreifen, im neuen muss ich das auch irgendwie ändern. Daher war meine Frage ob ich bei einer Operation wie
call matscaladd(i,mittelwert,1)
den Namen des Kanals erhalten kann und damit nicht vorher alle Namen einlesen und nachher wieder überschreiben muss? Denn kommen neue Kanäle durch kopieren etc. hinzu, verzettelt man sich schnell und es gibt Chaos...
Noch eine Frage: Ich habe Diadem 9.0 neu installiert und plötzlich gibt es bei dem Befehl:
call chncopy (cno("A"),C_Zwischenspeicher1)
die Fehlermeldung dass auf den Kanal C_Zwischenspeicher1 nicht zugegriffen werden kann. C_Zwischenspeicher 1 = 493 wird aber vorher zugewiesen und funktioniert auch einwandfrei unter anderem in anderen Diadem 9.0 Installationen. Es existieren nur Kanäle bis ca. Index = 63. Sollte aber in den alten Diadem Versionen kein Problem sein. Gibt es vielleicht eine kleine versteckte Option der dynamischen Kanalverwaltung in Diadem 9.0 die ich bei der Neuinstallation übersehen hab?
Noch eine letzte Frage zum Schluss:
Sollte ich mir jetzt lieber angewöhnen das Skript konsequent in die Objekt-orientierte Zugriffsweise umzuschreiben oder lieber bei den alten Codes bleiben?
Vielen Dank schon im Voraus für eure Hilfe!!!
P.S.: Raphael: Ich hatte wohl übersehen, dass ich bei den arrays nur dim name(501) initialisiert hatte aber sondentyp() übersehen hatte -.- Nachts um halb zwei darf das dann auch schonmal passieren...
11-20-2012 05:55 PM
Hallo Hummel3,
ich versche mal einige der Fragen zu beantworten. Das alte Script scheint noch sehr stark darauf aufzubauen, dass Kanäle über die Kanalnummer adressiert werden und die Speicherverwaltung der Kanäle in eine mehr oder weniger statischen Matrix erfolgt. Insbesondere der Teil mit den Kanalnummern entspricht in DIAdem schon seit einigen Jahren nicht mehr Stand der Technik. Genau genommen schon nicht mehr, seit mit DIAdem 9 Kanalgruppen eingeführt wurden.
So ganz verstehe ich das Problem mit den Kanalnamen die hin und her kopiert werden immer nocht nicht. DIAdem erlaubt bei den Mathefunktionen den Namen des Eingangskanals und den Namen des Ausgangskanals zu definieren. Sind beide Namen gleich werden die Daten "InPlace" bearbeitet. In dem Fall muss dann mit den Kanalnamen nichts besonderes gemacht werden.
Wahrscheinlich würde es dem Script gut tun wenn man es einmal renovieren würde und neuere Funktionen zum Einsatz bringt. Nicht nur, dass der Code wesentlich übersichtlicher werden sollte, es gibt auch Potential das ganze schneller zu machen.
Auf Dauer wird die Pflege schwierig werden wenn weiter Kanalnummern verwendet und darauf aufegbaut wird, dass eine statische Datenmatrix zugrunde liegt. Allein schon weil DIAdem die statische Datenmatrix in den neueren Versionen nicht mehr unterstützt.
Falls gewünscht, könnten wir (NI) uns das Script einmal ansehen und HInweise geben, wie die Umstellung effektiv erfolgen kann.
Andreas
11-21-2012 01:05 PM
Hallo AndreasH_Ha,
vielen Dank für die angebotene Hilfe, ich werde das mal mit den zuständigen Leuten bei uns abklären...
Vielleicht noch die Frage, wie ich bei einer Operation wie :
call matscaladd(i,mittelwert,1)
den Namen des Kanals erhalte?
Vielen Dank nochmals für die viele Hilfe,
Grüße Tim
11-22-2012 04:51 AM
Hallo Tim,
bei der Operation, so wie du sie beschrieben hast, wird der Kanalname bei mir erhalten da der Kanal mit Kanalnummer 1 einfach mit den berechneten Werten überschrieben wird.
Was passiert denn bei dir? Was passiert wenn du die 1 auf 0 setzt?
call matscaladd(i,mittelwert,0)
Raphael
11-24-2012 09:11 AM
Hi Lorenz-Mie,
finde die MatScal Operationen und die Einträge in der Hilfe von Diadem ein wenig verwirrend. Wenn ich bei MatScalMul hinten eine 0 angebe, legt er einen neuen Kanal am Ende der Liste mit dem Ergebnis an. Soweit so gut. Wenn ich den Wert nun aber auf 1 setze, überschreibt er den ersten Kanal von mtscalmul(kanal1, kanal2, 1) und benennt ihn in matscalmul um. D.h. ich muss vorher den Namen dieses Kanals sichern und ihn nachher zurück schreiben. Ziemlich umständlich...
Bei MatDiv gibt es so einen boolschen Operator wie 1 und 0 gar nicht. Dort wird das Ergebnis immer in den letzten Kanal geschrieben. Dann darf man das von da wieder in den Ursprungskanal schreiben und diesen dann wieder richtig benennen. Irgendwie ziemlich umständlich, das hätte man seitens National Instruments auch komfortabler programmieren können.
Eine weitere Anregung an Andreas:
Wenn ich ein Skript baue, mit dem verschiedene Berechnungen nacheinander durchgeführt werden können und dazu noch eine grafische Oberfläche gestalte, dann muss ich das ganze in der Entwicklungsphase auch debuggen können. Wenn ich nun einige Operationen durchlaufen habe (Buttons auf der grafischen Oberfläche entsprechen verschiedenen Berechnungsroutinen) und mir auf einmal in der folgenden routine ein fehler ausgegeben wird, sprich das Skript damit abbricht, habe ich ein Problem. Wenn ich den Fehler behoben habe, muss ich wieder alle Routinen von vorne durchklicken, da es keine Option gibt, den jeweiligen Stand komplett abzuspeichern. Damit meine ich nicht nur die Werte im Datenportal, sondern auch interne Variableninhalte, die im Skript verwendet werden... das ist sehr ägerlich und macht das debuggen von größeren Projekten entweder umständlich in der Programmierung (da man jede interne Variable zusätzlich im Datenportal abspeichert um so Zwischenstände laden zu können) oder sehr langwierig beim debuggen. Vielleicht kann man das für zukünftige Versionen ändern...?
Vielen Dank,
Grüße Tim