BT2k
HOME

VB-Quelltext zur Dekodierung des VC 840-Datenstroms

Vor einiger Zeit bot Conrad-Electronic ein Digitalmultimeter VC 840 mit serieller Schnittstelle an, das inzwischen weit verbreitet ist. Im Lieferumfang fand man ein fertiges Programm, welches die Messdaten als Tabelle oder als Kurve darstellen kann. Für die meisten Anwender wird das reichen, will man jedoch eigene Anwendungen schreiben, oder etwa zwei Multimeter gleichzeitig betreiben, so hilft diese Lösung nicht so richtig weiter.

Das Gerät liefert leider keinen ASCII-Datenstrom, sondern gibt die Anzeige nach einem sogenannten "FS9721-LPX RS232-Protokoll" aus (so der Hersteller). Das Protokoll wird in einem FAX-Dokument (erhältlich bei Conrad-Electronic) "121112-da-01-en-digitalmultimeter_vc840_schnittstellenp.pdf" beschrieben.Die hier vorgestellte Lösung eignet sich zum direkten Einsatz in Excel, wie im Buch Messen, Steuern, Regeln mit Word und Excel dargestellt ist.


Das Gerät sendet 14 Bytes über die RS232-Schnittstelle zum PC. Dabei ist die Übertragungsrate 2400 Bd, 8 Bit, keine Parität, 1 Stoppbit.

Der Hersteller liefert folgendes Beispiel für das verwendete 9721_LP3-Display: Bei unten abgebildeter Anzeige des Messgerätes werden 14 Bytes vom Multimeter gesendet:

15, 25, 3B, 40, 55, 67, 7D, 8F, 9E, A0, A0, B0, C0, D1, E1.

Diese Hexadezimalwerte beinhalten in der höherwertigen Tetrade (Bit 7 bis 4) die laufende Nummer des jeweiligen Bytes - also die Zahlen 1 bis 14 oder in hexadezimaler Form 1 bis E. In der niederwertigen Tetrade geben die Bits 3 bis 0 an, welche der Anzeigesegmente eingeschaltet sind. Die nachfolgende Tabelle zeigt den Zusammenhang:

Die nur sehr schwer lesbare vierzeilige Tabelle (Faxqualität) enthält die Informationen, die zur Dekodierung notwendig sind. Das erste Byte vom Multimeter (15h im Beispiel) enthält also die Informationen, ob die Anzeigelemente "RS232", "Auto", "DC" und "AC" angeschaltet sind. Dabei kan man die COM-Angaben als Bitwertigkeit der niederwertigen Tetrade betrachten. Der ersten Zeile der Tabelle ist das Bit 0 zugeordnet, der zweiten Zeile Bit 1 usw. Beim Byte 15 bleibt für die niederwertigen Bits der Wert 5 übrig. Dies ist binär der Wert 1001 und somit ist "RS232" und "AC" angeschaltet.

Im zweiten übertragenen Byte (hier 25h) bleibt ebenfalls der Binärwert 1001 für die Displaydekodierung übrig und aus der Tabelle folgt in Spalte 6 für das zweite Byte, dass Segment a1 der ersten 7-Segment-Anzeige leuchtet und das Vorzeichen "-" ebenfalls dargestellt wird. Im dritten Byte 3Bh sind demnach die Segmente an, deren Bit eine "1" enthält, wenn die Zahl 11 (Bh) binär 8+0+2+1 = 1011 dargestellt wird. Somit leuchten a2, a7 und a4. Der Dezimalpunkt hinter dem ersten Segment ist also aus.


Die hier dargestellte Lösung ist eine von mehreren Möglichkeiten aus dem Datenstrom eine ASCII-Darstellung zu erhalten.

Im Hauptprogramm (main) wird zunächst die RS232-Schnittstelle geöffnet. Anschließend wird das globale Datenarray mit den 14 Bytes gefüllt. Die Funktion "EineZeile" liefert auch das Byte als Zeichenkette, dies wird hier jedoch nicht benutzt. Es wird solange gewartet, bis das erste Byte angekommen ist. Somit stehen beim Verlassen der Funktion die Daten in der richtigen Reihenfolge im Speicher.

Die Routine "FillSeg" dekodiert die einzelnen Segmente der Anzeige.Der Übergabeparameter ist die Bytenummer. DecodeSeg vergleicht das Tabellenmuster mit den Bitmuster der 7-Segment-Zahlen und liefert dann den entsprechender Wert zurück. Im Hauptprogramm wird dieser numerische Wert wieder in eine Zeichenkette (String) eingebunden. Anschließend folgen noch Zehnerpotenz und Einheit.


Globale Variablen und Einstellungen
Declare Function OPENCOM Lib "RSAPI.DLL" (ByVal COM$) As Integer
Declare Function READBYTE Lib "RSAPI.DLL" () As Integer

Option Base 0
Dim Data(15) As Byte

Hilfsroutinen
Function EineZeile() As String
 Ix = 0
 A$ = ""
 While True
  e = READBYTE
  h = Hex(e)
  If Left$(h, 1) = "1" Then Ix = 1
  If Ix > 0 Then
   Data(ix + 1) = (e And 15)
   A$ = A$ + Mid$(h, 2, 1)
   Ix = Ix + 1
   EineZeile = A$
   If Ix > 14 Then Exit Function
  End If
 Wend
End Function

Function FillSeg(ByVal b) As Byte
 FillSeg = 0
 If (Data(b + 0) And 1) > 0 Then FillSeg = FillSeg Or 1 'a1
 If (Data(b + 1) And 1) > 0 Then FillSeg = FillSeg Or 2 'a2
 If (Data(b + 1) And 4) > 0 Then FillSeg = FillSeg Or 4 'a3
 If (Data(b + 1) And 8) > 0 Then FillSeg = FillSeg Or 8 'a4
 If (Data(b + 0) And 4) > 0 Then FillSeg = FillSeg Or 16 'a5
 If (Data(b + 0) And 2) > 0 Then FillSeg = FillSeg Or 32 'a6
 If (Data(b + 1) And 2) > 0 Then FillSeg = FillSeg Or 64 'a7
End Function

Function decodeSeg(ByVal seg) As Byte
 Dim Zahl(10) ' 1234567 Seg
 Zahl(0) = 63 ' 1111110 = 0
 Zahl(1) = 6 ' 0110000 = 1
 Zahl(2) = 91 ' 1101101 = 2
 Zahl(3) = 79 ' 1111001 = 3
 Zahl(4) = 99 ' 1100011 = 4
 Zahl(5) = 109 ' 1011011 = 5
 Zahl(6) = 125 ' 1011111 = 6
 Zahl(7) = 7 ' 1110000 = 7
 Zahl(8) = 255 ' 1111111 = 8
 Zahl(9) = 111 ' 1111011 = 9
 decodeSeg = 0
 For i = 0 To 9
   If seg = Zahl(i) Then decodeSeg = i
  Next i
End Function


Hauptroutine
Sub main()
 Dim segA, segB, segC, segD As Byte
 OPENCOM ("COM1:2400,N,8,1")
 While True
  DoEvents
  EineZeile
  segA = FillSeg(2)
  segB = FillSeg(4)
  segC = FillSeg(6)
  segD = FillSeg(8)
'Debug.Print decodeSeg(sega); decodeSeg(segB);
  A$ = ""
  'Bereich
  If (Data(1) And 4) > 0 Then A$ = A$ + "DC "
  If (Data(1) And 8) > 0 Then A$ = A$ + "AC "
  'Vorzeichen
  If (Data(2) And 8) > 0 Then A$ = A$ + "-"
  A$ = A$ + LTrim(Str$(decodeSeg(segA)))
  'Dezimalpunkt
  If (Data(4) And 8) > 0 Then A$ = A$ + ","
  A$ = A$ + LTrim(Str$(decodeSeg(segB)))
  'Dezimalpunkt
  If (Data(6) And 8) > 0 Then A$ = A$ + ","
  A$ = A$ + LTrim(Str$(decodeSeg(segC)))
  'Dezimalpunkt
  If (Data(8) And 8) > 0 Then A$ = A$ + ","
  A$ = A$ + LTrim(Str$(decodeSeg(segD)))
  A$ = A$ + " "
  'Einheit
  If (Data(10) And 2) > 0 Then A$ = A$ + "k"
  If (Data(10) And 4) > 0 Then A$ = A$ + "n"
  If (Data(10) And 8) > 0 Then A$ = A$ + "u"

  If (Data(11) And 2) > 0 Then A$ = A$ + "M"
  If (Data(11) And 4) > 0 Then A$ = A$ + "%"
  If (Data(11) And 8) > 0 Then A$ = A$ + "m"

  If (Data(12) And 2) > 0 Then A$ = A$ + "d"
  If (Data(12) And 4) > 0 Then A$ = A$ + "Ohm"
  If (Data(12) And 8) > 0 Then A$ = A$ + "F"

  If (Data(13) And 2) > 0 Then A$ = A$ + "Hz"
  If (Data(13) And 4) > 0 Then A$ = A$ + "V"
  If (Data(13) And 8) > 0 Then A$ = A$ + "A"
  Debug.Print A$
 Wend
End Sub

											

											

											 
											

										

Weitere Software
.
Startseite Bücher Software Digital RTV Musik Kontakt

Für Inhalt und weitere Verzweigung externer Links sind die Betreiber der dortigen Seiten verantwortlich - H.-J. Berndt