How to Send Hex Codes and Special Characters (like £) via Serial Port in VB.Net
The Challenge: Sending Non-Standard Characters to Customer Displays
When developing applications for Point of Sale (POS) hardware, such as the PartnerTech CD7220 Customer Display, you often need to send specific command bytes (hex codes) or special currency symbols (like the British Pound sign £).
If you are using the standard SerialPort.WriteLine() method in VB.Net, you might find that special characters are replaced with question marks (?) or garbled text. This happens because .NET defaults to UTF-8 or ASCII encoding, which translates characters outside the standard 127-character ASCII set into multi-byte sequences or unsupported placeholders.
In this article, we will look at the two best ways to solve this: writing raw hex bytes directly, and configuring the correct encoding on your serial port.
Solution 1: Send Raw Hex Bytes Directly (Recommended)
The most reliable way to send commands or specific character codes (like &HBC for the £ symbol on your display) is to bypass string encoding entirely and write a raw byte array directly to the serial port.
Here is how you can write a helper function to send raw bytes in VB.Net:
Imports System.IO.Ports
Public Sub SendHexToDisplay()
Dim mySerialPort As New SerialPort("COM3", 9600, Parity.None, 8, StopBits.One)
Try
mySerialPort.Open()
' Define your text as a byte array using ASCII for standard text
Dim line1 As Byte() = System.Text.Encoding.ASCII.GetBytes("Total Price: ")
' Define your hex code for the GBP symbol (£ is 0xBC / &HBC on the CD7220)
Dim gbpSymbol As Byte() = {&HBC}
Dim price As Byte() = System.Text.Encoding.ASCII.GetBytes("19.99")
Dim lineEnding As Byte() = System.Text.Encoding.ASCII.GetBytes(vbCrLf)
' Write everything sequentially to the port
mySerialPort.Write(line1, 0, line1.Length)
mySerialPort.Write(gbpSymbol, 0, gbpSymbol.Length)
mySerialPort.Write(price, 0, price.Length)
mySerialPort.Write(lineEnding, 0, lineEnding.Length)
Catch ex As Exception
MessageBox.Show("Error: " & ex.Message)
Finally
If mySerialPort.IsOpen Then
mySerialPort.Close()
End If
End Try
End SubSolution 2: Change the Serial Port Encoding
If you prefer to continue writing strings directly using mySerialPort.Write("£"), you must configure the SerialPort.Encoding property to match the character set (Code Page) configured on your customer display.
Most customer displays use an OEM code page like Code Page 850 (Western European) or Code Page 437 (US). If your display uses Code Page 850, where the £ symbol maps to 0xBC, you can initialize your port like this:
Dim mySerialPort As New SerialPort("COM3", 9600, Parity.None, 8, StopBits.One)
' Register the code pages provider if using .NET Core / .NET 5+
' System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance)
' Set the encoding to Code Page 850
mySerialPort.Encoding = System.Text.Encoding.GetEncoding(850)
mySerialPort.Open()
' Now you can send the string directly, and .NET will automatically encode "£" as 0xBC
mySerialPort.WriteLine("Total: £19.99")
mySerialPort.Close()Bonus: Proper Display Control (Clearing & Formatting)
Instead of sending blank spaces to clear the screen, you can send the official ESC/POS commands supported by the CD7220. According to the manual, the command to clear the screen and home the cursor is CLR (Hex 0x0C).
Here is a clean, robust implementation using these practices:
Public Sub UpdateDisplay(line1Text As String, line2Text As String)
Dim mySerialPort As New SerialPort("COM3", 9600, Parity.None, 8, StopBits.One)
mySerialPort.Encoding = System.Text.Encoding.GetEncoding(850) ' Matches display character map
Try
mySerialPort.Open()
' Send Clear Screen Command (Hex 0x0C)
Dim clearCmd As Byte() = {&H0C}
mySerialPort.Write(clearCmd, 0, clearCmd.Length)
' Send formatted lines (truncated to 20 characters)
mySerialPort.WriteLine(line1Text.PadRight(20).Substring(0, 20))
mySerialPort.WriteLine(line2Text.PadRight(20).Substring(0, 20))
Catch ex As Exception
' Handle connection errors
Finally
mySerialPort.Close()
End Try
End SubConclusion
By either switching to byte array writes or setting the correct Code Page encoding on your SerialPort object, you can seamlessly send any hex command or international currency symbol to your hardware peripherals without compatibility issues.