Seite 1 von 2
Code Snippets
Verfasst: Fr 5. Aug 2011, 23:41
von Kabelitz
Die Erstellung von Software unter Windows für GSV-2, GSV-3 und GSV-4 Messverstärker geht am besten mit der entsprechenden Windows-DLL.
megsv.dll für GSV-2 und GSV-3
megsv4.dll für GSV-4
Was ist mit Android?
Hier helfen vermutlich die Code-Snippets.
Anbei der Quelltext, der für ein Experiment mit GSV-3BT und Windows-Mobile 5 unter "Pocket-Zeus Basic" geschrieben wurde.
Von Zeile 366 bis 797 sind die wesentlichen Funktionen untergebracht...
Vielleicht hilft der Code, die Bedienungsanleitung ba-gsv3.pdf zu verstehen.
Code: Alles auswählen
' ***************************************************************************
func gsvstop()
ComOutput(Channel1,chr(35))
endfunc
' ***************************************************************************
func gsvstart()
ComOutput(Channel1,chr(36))
endfunc
' ***************************************************************************
func gsvsetzero()
ComOutput(Channel1,chr(14))
pause(1000)
ComOutput(Channel1,chr(12))
playsound("xx")
endfunc
' ***************************************************************************
func gsvsetfrequency(freq as integer)
dim line as string
protocol = 2
' gsvstop()
' pause(1000)
' ComPurge(Channel1)
line = Chr($8A)+Chr($08)+Chr($B3)+Chr($B4)
select integer freq
case 1
line = Chr($8A)+Chr($08)+Chr($B3)+Chr($B4)
case 10
line = Chr($8A)+Chr($08)+Chr($F8)+Chr($5F)
case 20
line = Chr($8A)+Chr($07)+Chr($F8)+Chr($5F)
case 50
line = Chr($8A)+Chr($07)+Chr($FC)+Chr($F3)
case 100
line = Chr($8A)+Chr($06)+Chr($FC)+Chr($F3)
endselect
ComOutput(Channel1,line)
pause(1000)
gsvfrequency = gsvGetFrequency()
gsvintervall = 1/gsvfrequency
cgsvfrequency = formatvalue(1000.0,gsvfrequency)+" Hz"
cgsvintervallformat = getformatstring(100.0,gsvintervall)
FormLabel(Main_Frequency,-1,-1,-1,-1,cgsvfrequency)
protocol = 2
gsvstart()
endfunc
' ***************************************************************************
func gsvGetSerialNumber() as string
dim line as string
ComPurge(Channel1)
ComOutput(Channel1,chr(31))
pause(2000)
line = gsvreadline(2000)
' print line
exit(line)
endfunc
' ***************************************************************************
func gsvGetFrequency() as single
dim highbyte, midbyte, lowbyte as integer
dim i, inbyte as integer
dim inchar as string
dim line as string
ComPurge(Channel1)
ComOutput(Channel1,chr(22))
pause(1000)
line = gsvreadline(2000)
' print line
for i = 1 to 4
inchar = Mid(line,i,1)
inbyte = Asc(inchar)
' print inbyte
ongosub i-1, label0, label1, label2, label3
next
gsvfrequency=5000000.0/(16777216.0-((highbyte*65536.0)+(midbyte*256.0)+lowbyte))
' gsvfrequency = (highbyte*65536.0)+(midbyte*256.0)+lowbyte
' gsvfrequency = 16777216.0 - gsvfrequency
' gsvfrequency = 5000000.0 / gsvfrequency
' print "gsvfrequency=";gsvfrequency
exit(gsvfrequency)
label0:
return
label1:
highbyte = inbyte
return
label2:
midbyte = inbyte
return
label3:
lowbyte = inbyte
return
endfunc
Einzelwertabfrage
Verfasst: Di 16. Aug 2011, 21:11
von Kabelitz
Die Einzelwertabfrage ist bei GSV-2, GSV-3 und GSV-4 mit getvalue möglich.
Der Befehl getvalue wird ausgeführt, indem man ein ; (Semikolon, Zeichen 0x3B, ASCII 59) sendet.
Vorher sollte man den Messverstärker aber so konfigurieren, dass er nur noch auf getvalue einen Messwert sendet.
Das kann man auf verschiedene Arten tun.
a)
bei GSV-2 und GSV-3: man sendet StopTransmit. (Zeichen 0x23, ASCII 35)
Allerdings merkt sich der GSV-2/3 diesen Zustand nicht. Nach dem Aus/Einschalten sendet er wieder fleißig mit der eingestellten Frequenz.
Damit sich der GSV-2/GSV-3 diesen Zustand merkt, muss man ihn in den "Logger" Modus versetzen, (Einzelwertabfrage).
Dann wird gleichzeitig der digitale Eingang zum Nullsetzen umfunktioniert zu einem digitalen Eingang für die Einzelwertabfrage (Triggereingang).
b)
Für den Logger-Modus muss man bei GSV-2 und GSV-3 das Status Register verändern.
Am einfachsten erreicht man das, indem man die Software GSVControl aufruft. In der Karteilkarte "Experte" gibt es eine Checkbox "Logger-Modus". Diese muss man aktivieren.
Einzelwertabfrage ein- ausschalten
Verfasst: Fr 19. Aug 2011, 22:20
von Kabelitz
Um die Datenübertragung bei GSV-2 und GSV-3 dauerhaft auszuschalten, muss der "Logger-Mode" gesetzt werden.
Für den Logger-Mode muss Bit 3 im Mode Register auf 1 gesetzt werden.
Die macht man am besten, indem man erst den aktuellen Zustand des Modus-Registers ausliest und eine Oder Verknüpfung mit 0x08 durchführt.
Anbei ist der Perl Code für das Ein- und Ausschalten des Einzelwert-Modus.
Code: Alles auswählen
sub set_modelog
{
my ($portobj, $loggermode) = @_;
my ($kommando);
my (@params, @bytes_from_gsv);
my ($modus, $muster, $check_protokoll);
# aktuelles Modus Register auslesen:
$kommando = "gsvgetmode";
@params = ();
# Kommando gsvgetmode ausführen:
(@bytes_from_gsv) = &gsv_command($portobj, $kommando, @params);
$modus = $bytes_from_gsv[0];
if ($loggermode == 1)
{
# Logger-Modus (Einzelwertabfrage) soll eingeschaltet werden:
$muster = "\x08";
# aktuellen Modus und Logger Modus mit ODER verknüpfen:
$check_protokoll = $modus | $muster;
# Modus setzen:
$kommando = "gsvsetmode";
@params = ($check_protokoll);
(@bytes_from_gsv) = &gsv_command($portobj, $kommando, @params);
}
elsif ($loggermode == 0)
{
# Logger-Modus (Einzelwertabfrage) soll ausgeschaltet werden:
$muster = "\xF7";
# aktuellen Modus und Logger Modus mit UND verknüpfen:
$check_protokoll = $modus & $muster;
# Modus setzen:
$kommando = "gsvsetmode";
@params = ($check_protokoll);
(@bytes_from_gsv) = &gsv_command($portobj, $kommando, @params);
}
}
Messfrequenz auslesen
Verfasst: Fr 19. Aug 2011, 22:37
von Kabelitz
Bei den Messverstärkern GSV-2 und GSV-3 lässt sich die Frequenz auslesen, mit der ein neuer Messwert zur Verfügung steht.
Wenn der Einzelwertmodus NICHT eingeschaltet ist, dann werden die Messwerte mit dieser Frequenz über die Schnittstelle gesendet.
Achtung: Auch im Einzelwertmodus sollte die Frequenz sinnvoll eingestellt sein.
Es macht keinen Sinn, die Messfrequenz auf 1Hz zu stellen und mit 50Hz die Werte abzuholen. Man bekommt dann eben 50x den gleichen Messwert!
Ein Basic Code Snippet zu gsvgetfrequency hatten wir schon, hier ist der Code in Perl:
Code: Alles auswählen
sub get_frequency{
my ($portobj) = @_;
my (@out, @params, @bytes_from_gsv);
my ($frequency);
(@bytes_from_gsv) = &gsv_command ($portobj, "gsvgetfrequency", @params);
@out = (ord($bytes_from_gsv[0]), (ord($bytes_from_gsv[1])), (ord($bytes_from_gsv[2])));
$frequency=5000000/(16777216-($out[0]*65536+$out[1]*256+$out[2]));
return ($frequency);
};
Einheit lesen und schreiben
Verfasst: Fr 19. Aug 2011, 22:57
von Kabelitz
Nur der Vollständigkeit halber: Lesen und Schreiben der Einheit.
Wichtig: das Setzen der Einheit hat keinerlei Einfluss auf die Skalierung der Messwerte.
Es handelt sich nur um eine Information, die Im EEProm des Messverstärkers abgelegt wird.
Weiter oben hatten wir schon ein Basic-Beispiel...
Code: Alles auswählen
sub get_unit{
my ($portobj) = @_;
my (@units, @params);
my @bytes_from_gsv;
my $unit;
@units=("mV/V","kg","g","N","cN","V","µm/m","","t","kN","lb","oz","kp","lbf","pdl","mm","m","cNm","Nm");
(@bytes_from_gsv) = &gsv_command ($portobj, "gsvgetunit", @params);
$unit = ord($bytes_from_gsv[0]);
# gibt den Index der Einheit zurück, nicht die Einheit als string:
return ($unit);
};
sub set_unit{
my ($portobj, $unit) =@_;
my (@params);
my @bytes_from_gsv;
my (@units);
my ($i, $item);
@units=("mV/V","kg","g","N","cN","V","µm/m","","t","kN","lb","oz","kp","lbf","pdl","mm","m","cNm","Nm");
$i = 0;
foreach $item (@units)
{
if($item eq $unit)
{
$unit = $i;
}
$i++;
}
@params = chr($unit);
(@bytes_from_gsv) = &gsv_command ($portobj, "gsvsetunit", @params);
};
Bits im Modus Register prüfen
Verfasst: Fr 19. Aug 2011, 23:04
von Kabelitz
Code: Alles auswählen
sub get_modetext
{
my ($portobj) = @_;
my ($kommando);
my (@params, @bytes_from_gsv);
my ($modus, $muster, $check_protokoll);
# Modus überprüfen:
$kommando = "gsvgetmode";
@params = ();
($l1, $line, @bytes_from_gsv) = &gsv_command($portobj, $kommando, @params);
$modus = $bytes_from_gsv[0];
$muster = "\x02";
$check_protokoll = $modus & $muster;
if ( $check_protokoll ne "\x02")
{
# Binärprotokoll
return (1);
}
else
{
# Textprotokoll
return (0);
}
}
sub get_modewindow
{
my ($portobj) = @_;
my ($kommando);
my (@params, @bytes_from_gsv);
my ($modus, $muster, $check_protokoll);
# Modus überprüfen:
$kommando = "gsvgetmode";
@params = ();
($l1, $line, @bytes_from_gsv) = &gsv_command($portobj, $kommando, @params);
$modus = $bytes_from_gsv[0];
$muster = "\x10";
$check_protokoll = $modus & $muster;
if ($check_protokoll ne "\x10")
{
# Windowmode ist aus:
return (0);
}
else
{
# Windowmode ist an
return (1);
}
}
sub get_modelog
{
my ($portobj) = @_;
my ($kommando);
my (@params, @bytes_from_gsv);
my ($modus, $muster, $check_protokoll, $cond);
# Modus überprüfen:
$kommando = "gsvgetmode";
@params = ();
($l1, $line, @bytes_from_gsv) = &gsv_command($portobj, $kommando, @params);
$modus = $bytes_from_gsv[0];
$muster = "\x08";
$check_protokoll = $modus & $muster;
if ( $check_protokoll ne "\x08")
{
return (0);
}
else
{
return (1);
}
}
Schwellwert lesen / setzen
Verfasst: Fr 19. Aug 2011, 23:09
von Kabelitz
Code: Alles auswählen
sub get_threshold1
{
my ($portobj, $mbendwert) = @_;
my ($hb_on, $lb_on, $hb_off, $lb_off);
my ($sw_on, $sw_off);
my (@bytes_from_gsv, @params);
(@bytes_from_gsv) = &gsv_command ($portobj, "gsvgetthreshold1", @params);
$hb_on = ord($bytes_from_gsv[0]);
$lb_on = ord($bytes_from_gsv[1]);
$hb_off = ord($bytes_from_gsv[2]);
$lb_off = ord($bytes_from_gsv[3]);
$sw_on = (($lb_on + $hb_on * 256) - 32767)/32768 * 1.05 * $mbendwert ;
$sw_off = (($lb_off + $hb_off * 256) - 32767)/32768 * 1.05 * $mbendwert ;
return ($sw_on, $sw_off);
};
Code: Alles auswählen
sub set_threshold1
{
my ($portobj, $schwellwert, $schwellwert_aus, $mbendwert) = @_;
my ($lowbyte_einschwelle, $highbyte_einschwelle, $lowbyte_ausschwelle, $highbyte_ausschwelle);
my (@params);
my (@bytes_from_gsv);
$schwellwert = sprintf ("byte 0x%04X", ($schwellwert/$mbendwert)/1.05*32768+32768);
$schwellwert_aus = sprintf ("byte 0x%04X", ($schwellwert_aus/$mbendwert)/1.05*32768+32768);
$highbyte_einschwelle = chr(hex(substr($schwellwert,-4,2))); #umwandeln in ein zeichen
$lowbyte_einschwelle = chr(hex(substr($schwellwert,-2,2)));
$highbyte_ausschwelle = chr(hex(substr($schwellwert_aus,-4,2)));;
$lowbyte_ausschwelle = chr(hex(substr($schwellwert_aus,-2,2)));
@params = ($highbyte_einschwelle, $lowbyte_einschwelle, $highbyte_ausschwelle, $lowbyte_ausschwelle);
&gsv_command ($portobj, "gsvsetthreshold1", @params);
return 0;
};
getall-Parametersatz laden
Verfasst: Mi 24. Aug 2011, 16:37
von Kabelitz
Mit der Funktion getall lassen sich bei GSV-2 und GSV-3 komplette Parametersätze laden,
sprich komplette Konfigurationen herstellen.
Also eine gewünschte Samplingrate, gewünschet Einheit, gewünschtes Datenformat, Schwellwert-Konfiguration.
Bis zu 6 Konfigurationen kann man im EEProm ablegen.
Achtung: die Parameter von getall haben den Wertebereich von $00 bis $07, und nicht die ASCII Zeichen "0" bis "7".
Dazu muss die Funktion "getall" aufgerufen werden.
"getall" hat nur einen Parameter.
$01: Hersteller-Konfiguration
$02 ...$07: eigene Konfigurationen
Hier ist ein Basic Beispiel
Code: Alles auswählen
func gsvgetall(user as integer)
dim line as string
line = Chr($09)+Chr(user - 48)
ComOutput(Channel1,line)
pause(1000)
endfunc
Re: Code Snippets
Verfasst: So 15. Jan 2012, 19:33
von Kabelitz
Gibt es ein Beispiel für die Synchronisation beim GSV-3BT im Binär-Protokoll?
Das Startbyte ist 0xA5, dann folgen HighByte und LowByte. Prinzipiell kann aber 0xA5 auch im High-Byte oder Low Byte vorkommen.
Wie macht man das sicher?
Außerdem: wie erkennt man am einfachsten, ob es sich um einen GSV-4BT oder GSV-3BT handelt?
Re: Code Snippets
Verfasst: Fr 29. Jun 2012, 16:18
von Wetz
Synchronisation der Messwertbytes GSV-3
1. Nach Öffnen der Schnittstelle: einmal stopTX (Cmd. 0x23), dann ggf Software-Buffer löschen, dann startTX (Cmd 0x24) geben.
Dadurch beginnt der GSV-3 auf jeden Fall mit einem kompletten Frame.
2. Nun werden 2 Zustände unterschieden: a) Hohe Datenrate und b) niedrige Datenrate. Wo der Umbruch der Datenraten ist,
hängt davon ab, unterhalb welcher Datenrate das Kommunikationssystem (Bluetooth, USB) nur noch einen Messwert in einen
Kommunikationsframe packt. Es wird dabei davon ausgegangen, daß bei hoher Datenrate (a) das Lowbyte des Messwertes rauscht,
d.h. daß es nie mehr als zweimal nacheinander denseben Wert hat. Dabei ist der kritische Wert der des Präfixes, d.h. 0xA5,
da hierbei Fehlsynchronisation droht.
Prinzipiell wird immer erst ein Byte gelesen; ist dieses =0xA5, werden 2 weitere Bytes gelesen, von denen angenommen wird, es seien Messwertbytes.
Ist das erste gelesene Byte nicht A5, wird es verworfen
2 a) Lese drei Messwertframes und speichere diese. Wenn das vermeindliche Lowbyte des Messwertes bei allen 3 =0xA5 ist, ist folgende Fehlsynchronisation der Fall:
Wahre Frames: A5A5xx A5A5xx A5A5xx A5A5xx
Gelesene Frames: A5xxA5 A5xxA5 A5xxA5
Dann die nächsten 2 Bytes ungeachtet ihres Wertes verwerfen, d.h. das nächste A5 und das Byte dannach zwar lesen, aber nicht beachten.
Dann wieder ein Byte lesen und auf Präfix auswerten, u.s.w.
2 b) Bei niedriger Datenrate wird davon ausgegangen, daß zwischen 2 Messwertframes ein zeitlicher Abstand ist, den das
Kommunikationssystem nicht auffüllt. Hiebei:
Immer erst Einzelbytes versuchen zu lesen (d.h. vom Empfangspuffer holen). Wenn KEIN Byte gelesen wurde, einen zeitlichen Zwischenraum annehmen
und ein "Präfix-Erwartungsflag" setzen. Wenn nun ein Präfix gelesen wurde und diese Flag gesetzt ist, werden die beiden Messwertbytes gelesen.
Ist es nicht gesetzt, Einzelbytes lesen, bis kein Byte gelesen wurde (d.h. bis zum Zeitabstand), u.s.w.
Der Knackpunkt dieser Methoden sind Datenraten, bei denen das Lowbyte noch nicht rauscht, dennoch bereits mehrere Messwerte in einen
Kommunikationsframe gepackt werden, so daß am Empfangsgerät kein zeitlicher Abstand zwischen den Messwerten zu detektieren ist.
Dann wird das leider kaum funktionieren, da das Lowbyte auch oft nacheinander =0xA5 sein könnte.
Vielleicht können wir die Kommunikationssysteme (USB-chip bzw Bluetooth-Modul) so konfigurieren, daß wir die Wartezeit
verändern, die es auf Bytes wartet, bis diese in einem Kommunikationsframe gesendet werden, und diese Zeit anhand der
Grenzdatenrate des o.g. Algorithmus einstellen.