Reputation: 215
As a hobby I'm interesting in programming an Ethernet-connected LED sign to scroll messages across a screen. But I'm having trouble making a UDP sender in VB.NET (I am using 2008 currently).
Now the sign is nice enough to have a specifications sheet on programming for it.
But an example of a line to send to it (page 3):
<0x01>Z30<0x02>AA<0x06><0x1B>0b<0x1C>1<0x1A>1This message will show up on the screen<0x04>
With codes such as <0x01> representing the hex character.
Now, to send this to the sign I need to use UDP. However, the examples I have all encode the message as ASCII before sending, like this one (from UDP: Client sends packets to, and receives packets from, a server):
Imports System.Threading
Imports System.Net.Sockets
Imports System.IO
Imports System.Net
Public Class MainClass
Shared Dim client As UdpClient
Shared Dim receivePoint As IPEndPoint
Public Shared Sub Main()
receivePoint = New IPEndPoint(New IPAddress(0), 0)
client = New UdpClient(8888)
Dim thread As Thread = New Thread(New ThreadStart(AddressOf WaitForPackets))
thread.Start()
Dim packet As String = "client"
Console.WriteLine("Sending packet containing: ")
'
' Note the following line below, would appear to be my problem.
'
Dim data As Byte() = System.Text.Encoding.ASCII.GetBytes(packet)
client.Send(data, data.Length, "localhost", 5000)
Console.WriteLine("Packet sent")
End Sub
Shared Public Sub WaitForPackets()
While True
Dim data As Byte() = client.Receive(receivePoint)
Console.WriteLine("Packet received:" & _
vbCrLf & "Length: " & data.Length & vbCrLf & _
System.Text.Encoding.ASCII.GetString(data))
End While
End Sub ' WaitForPackets
End Class
To output a hexcode in VB.NET, I think the syntax may possibly be &H1A - to send what the specifications would define as <0x1A>.
Could I modify that code, to correctly send a correctly formated packet to this sign?
The answers from Grant (after sending a packet with hex in it), Hamish Smith (using a function to get hex values), and Hafthor (hardcoded chr() message into example) when attempted all did not work. So I'll research to see what else could go wrong. In theory, if this string is sent successfully, I should have a message containing "OK" back, which will help to know when it works.
I have tried and am now able to monitor the packets going through. A working packet example is this (in raw hex): http://www.brettjamesonline.com/misc/forums/other/working.raw vs my version: http://www.brettjamesonline.com/misc/forums/other/failed.raw. The difference is my hex codes are still not encoded correctly, seen in this side-by-side image: http://www.brettjamesonline.com/misc/forums/other/snapshotcoding.png.
I have used this code to generate the packet and send it:
container = &H1 & "Z" & &H30 & &H2 & "temp.nrg" & &H1C & "1Something" & &H4
' This did not appear to work neither
'container = Chr(&H1) & "Z" & Chr(&H30) & Chr(&H2) & Chr(&H1C) & "1Something" & Chr(&H4)
'<0x01>Z00<0x02>FILENAME<0x1C>1Test to display<0x04> <- the "official" spec to send
Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes(container)
(Full snippet: http://pastebin.com/f44417743.)
Upvotes: 3
Views: 12777
Reputation:
They posted libraries for a bunch of languages including Visual Basic (in the separate file). I tested the demos out with one of their signs and they work!
Upvotes: 0
Reputation: 16916
You could put together a quickie decoder like this one:
Function HexCodeToHexChar(ByVal m as System.Text.RegularExpressions.Match) As String
Return Chr(Integer.Parse(m.Value.Substring("<0x".Length, 2), _
Globalization.NumberStyles.HexNumber))
End Function
then use this to transform:
Dim r As New System.Text.RegularExpressions.Regex("<0x[0-9a-fA-F]{2}>")
Dim s As String = r.Replace("abc<0x44>efg", AddressOf HexCodeToHexChar)
' s should now be "abcDefg"
you could also make an encoder function that undoes this decoding (although a little more complicated)
Function HexCharToHexCode(ByVal m As Match) As String
If m.Value.StartsWith("<0x") And m.Value.EndsWith(">") And m.Value.Length = "<0x??>".Length Then
Return "<0<0x78>" + m.Value.Substring("<0x".Length)
ElseIf Asc(m.Value) >= 0 And Asc(m.Value) <= &HFF Then
Return "<0x" + Right("0" + Hex(Asc(m.Value)), 2) + ">"
Else
Throw New ArgumentException("Non-SBCS ANSI characters not supported")
End If
End Function
and use this to transform:
Dim r As New Regex("[^ -~]|<0x[0-9a-fA-F]{2}>")
Dim s As String = r.Replace("abc"+chr(4)+"efg", AddressOf HexCharToHexCode)
' s should now be "abc<0x04>efg"
or you could just build the string with the special characters in it to begin with like this:
Dim packet As String = Chr(&H01) + "Z30" + Chr(&H02) + "AA" + Chr(&H06) + _
Chr(&H1B) + "0b" + Chr(&H1C) + "1" + Chr(&H1A) + _
"1This message will show up on the screen" + Chr(&H04)
for sending a UDP packet, the following should suffice:
Dim i As New IPEndPoint(IPAddress.Parse("192.168.0.5"), 3001) ''//Target IP:port
Dim u As New UdpClient()
Dim b As Byte() = Encoding.UTF8.GetBytes(s) ''//Where s is the decoded string
u.Send(b, b.Length, i)
Upvotes: 2
Reputation: 8181
The UDP client sends an array of bytes.
You could use a memory stream and write bytes to an array.
Public Class MainClass
Shared client As UdpClient
Shared receivePoint As IPEndPoint
Public Shared Sub Main()
receivePoint = New IPEndPoint(New IPAddress(0), 0)
client = New UdpClient(8888)
Dim thread As Thread = New Thread(New ThreadStart(AddressOf WaitForPackets))
thread.Start()
Dim packet As Packet = New Packet("client")
Console.WriteLine("Sending packet containing: ")
Dim data As Byte() = packet.Data
client.Send(data, data.Length, "localhost", 5000)
Console.WriteLine("Packet sent")
End Sub
Public Shared Sub WaitForPackets()
While True
Dim data As Byte() = client.Receive(receivePoint)
Console.WriteLine("Packet received:" & _
vbCrLf & "Length: " & data.Length & vbCrLf & _
System.Text.Encoding.ASCII.GetString(data))
End While
End Sub ' WaitForPackets
End Class
Public Class Packet
Private _message As String
Public Sub New(ByVal message As String)
_message = message
End Sub
Public Function Data() As Byte()
Dim ret(13 + _message.Length) As Byte
Dim ms As New MemoryStream(ret, True)
ms.WriteByte(&H1)
'<0x01>Z30<0x02>AA<0x06><0x1B>0b<0x1C>1<0x1A>1This message will show up on the screen<0x04>
ms.Write(System.Text.Encoding.ASCII.GetBytes("Z30"), 0, 3)
ms.WriteByte(&H2)
ms.Write(System.Text.Encoding.ASCII.GetBytes("AA"), 0, 2)
ms.WriteByte(&H6)
ms.Write(System.Text.Encoding.ASCII.GetBytes("0b"), 0, 2)
ms.WriteByte(&H1C)
ms.Write(System.Text.Encoding.ASCII.GetBytes("1"), 0, 1)
ms.WriteByte(&H1A)
ms.Write(System.Text.Encoding.ASCII.GetBytes(_message), 0, _message.Length)
ms.WriteByte(&H4)
ms.Close()
Data = ret
End Function
End Class
Upvotes: 0
Reputation: 12049
This might help. At my company we have to communicate with our hardware using sort of a combination of ascii and hex.
I use this function to hexify ip addresses before sending them to the hardware
Public Function HexFromIP(ByVal sIP As String)
Dim aIP As String()
Dim sHexCode As String = ""
aIP = sIP.Split(".")
For Each IPOct As String In aIP
sHexCode += Hex(Val(IPOct)).PadLeft(2, "0")
Next
Return sHexCode
End Function
And occationally I use hexSomething = Hex(Val(number)).PadLeft(2,"0")
as well.
I can give you the source for the whole program too, though it's designed to talk to different hardware.
EDIT:
Are you trying to send packets in hex, or get packets in hex?
Upvotes: 0