Forum: PC-Programmierung VB 2005 Ascii Chr() Problem


von Robert (Gast)


Lesenswert?

Hallo Zusammen,

ich habe eine Routine zum berechnen einer Checksumme für die RS232 
Kommunikation mit einem Gerät. Die Checksumme bildet sich aus dem 
aufaddieren der einzelnen Bytes im Protokoll, dann Bit 9-... abschneiden 
und dem anschließendem "1" setzen des MSB. Jetzt muss ich das ganze über 
die RS232 in den Atmel schicken.
Für die Programmierung nutzte ich VB.net 2005. Mein Problem dabei ist 
nun folgendes:

Meine Checksumme ist als Integer deklariert und wird auch richtig 
berechnet. Allerdings kann ich ja eine "181" (errechnete Checksumme als 
Decimal) nicht einfach als String wandeln und über RS232 schicken, weil 
ja daraus ein "0x31 0x38 0x31" gemacht wird. Um dieses Problem zu lösen, 
wollte ich die Funktion chr() nutzen. Allerdings funktioniert das nur 
bis 127. Sobald es in den erweiterten Ascii reingeht (was ja 181 ist) 
kommt immer "0x3F" raus.

Wie kann ich in VB.Net 2005 eine Dezimalzahl (128-255) in das 
dazugehörige Ascii-Zeichen umwandeln?

Grüße Robert

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> Allerdings funktioniert das nur bis 127.
> Sobald es in den erweiterten Ascii reingeht (was ja 181 ist)
> kommt immer "0x3F" raus.

Könnte es sein, daß Du keine 8-Bit-Übertragung auf der seriellen 
Schnittstelle verwendest? Welche Kommunikationsparameter hast Du 
eingestellt? Welchen Datentyp verwendest Du für die Zuweisung des 
Ergebnisses von chr()?
Quelltext?

von Robert (Gast)


Lesenswert?

Hallo Rufus,

meine Parameter sind 8N1 und 9600Baud. Hier ist der Code.

Public Function CheckUnit(ByVal sp As System.IO.Ports.SerialPort) As 
Boolean
        Dim sSendData As String = "123456abcdef"
        Dim chkSum As Char = CheckSum(sSendData)

        If sp.IsOpen = False Then
            sp.Open()
            sp.Write(sStart)
            For Each letter As String In sSendData
                sp.Write(letter)
            Next
            sp.Write(chkSum)
            sp.Write(sEnd)
            sp.Close()
        End If

        Return True // im Moment ohne Funktion
    End Function


    Private Function CheckSum(ByVal protocol As String) As Char
        Dim chk As Integer = 0

        For Each letter As String In protocol
            chk = chk + Asc(letter)
        Next

        chk = chk And 255

        Return Convert.ToChar(chk Or 128)
    End Function

Wie gesagt. Bis Ascii 127D funktioniert alles super.
Vielleicht findest Du ja was.


von sebastian___ (Gast)


Lesenswert?

Hallo,
mache das doch mit bytes und der funktion:

System.Text.Encoding encoder = new ASCIIENCODER();
byte[] buffer= encoder.GetBytes("das ist der Text");


und rückwärts gehts dann so:
string text= encoder.GetString(buffer);


Das sollte so ganz gut funktionieren. Musst halt nur VB Syntax draus 
machen.

Sebastian

von Robert (Gast)


Lesenswert?

Das habe ich auch schon versucht. Das Problem liegt darin, dass der 
Ascii-Encoder nur mit dem 7-Bit Ascii Code arbeitet.
Kennt jemand eine Methode, damit ich den Hexwert einer Dezimalzahl 
zwischen 0 und 255 über die RS232 schicken kann?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Das Problem ist in der Dokumentation von 
System.IO.Ports.SerialPort.Write beschrieben (genauer: der Variante 
davon, die ein Byte-Array sendet):


By default, SerialPort uses ASCIIEncoding to encode the characters. 
ASCIIEncoding encodes all characters greater then 127 as (char)63 or 
'?'. To support additional characters in that range, set Encoding to 
UTF8Encoding, UTF32Encoding, or UnicodeEncoding.

von Robert (Gast)


Lesenswert?

Hallo Rufus,

danke für den Tip.

Ich habe jetzt eine andere Lösung gefunden. So sieht der aktuelle Code 
aus.

Public Function CheckUnit(ByVal sp As System.IO.Ports.SerialPort) As 
Boolean
        Dim sSendData As String = "123456abcdef"
        Dim chkSum As Byte = CheckSum(sSendData)

        If sp.IsOpen = False Then
            sp.Open()
            sp.Write(sStart)
            For Each letter As String In sSendData
                sp.Write(letter)
            Next
            sp.BaseStream.WriteByte(chkSum)
            sp.Write(sEnd)
            sp.Close()
        End If

        Return True
    End Function


    Private Function CheckSum(ByVal protocol As String) As Byte
        Dim chk As Integer = 0

        For Each letter As String In protocol
            chk = chk + Asc(letter)
        Next

        chk = chk And 255
        chk = chk Or 128

        Return Convert.ToByte(chk)
    End Function


Kann es durch den Zugriff auf den BaseStream zu unerwarteten Problemen 
kommen?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.