近頃はぐずついた天気の日が多いので、無線小屋に籠ってプログラミングをして過ごしています。以前製作したお月様自動追尾装置を改良しています。従来は、ESP32を使ってWiFiでTCP/IP通信をしていましたが、144.120MHz近傍にノイズが出るので、アンテナの近くに置くESP32ではWiFiの代わりにRS485を使い、アンテナから離れた場所に設置するESP32でRS485-WiFiブリッジを作成して通信するようにします。通信にはUDP/IPを使うこととし、RS485-WiFiブリッジは固定IPアドレスと固定UDPポートを持つこととします。PCから見れば、RS485-WiFiブリッジにコマンドをUDPパケットで送るとお月様自動追尾装置に中継されて、そのレスポンスがRS485-WiFiブリッジを経由してUDPパケットで返ってくるという仕組みです。
前置きが長くなりましたが、上記のアプリを作成するためのUDP通信関数を作成しました。関数は一つだけなので、とてもシンプルです。その関数は、UdpCmdRspという名前で、次のように定義します。
Public Function UdpCmdRsp(ByVal srcPort As Integer, 'local UDP port
ByVal destIP As String, 'remote IP address
ByVal destPort As Integer, 'remote UDP port
ByVal cmd As String, 'command message
ByVal cmdOnly As Boolean, 'set true when command only message
ByRef rsp As String 'response message
) As Boolean 'true when response is available
UDPでコマンドを送って、それに対するレスポンスを得るという方式であれば、この関数を呼ぶだけで一連の動作を行うことができるようにしました。ソケットを作るとかエンドポイントがどうだとかという細々したことは全部覆い隠してしまいました。この関数だけをコピペして、作成したいアプリに貼り付けるだけで利用できます。
この関数を使って、UDP tesl toolというアプリを作成しました。右のCOM12という画面はRS485-WiFiブリッジの内部情報を表示したものです。
ソースコードを以下に示します。(これで全部です。)
'project name: TestUDPgateway
'File name Form1.vb
'Test tool for the dvice which resepond to UDP
'author H.NAMVA JH4ADK created on 2023.11.18
' revised on 2024.03.24: make it simple
Imports System.Text
Imports System.Net.Sockets
Public Class Form1
Public Function UdpCmdRsp(ByVal srcPort As Integer, 'local UDP port
ByVal destIP As String, 'remote IP address
ByVal destPort As Integer, 'remote UDP port
ByVal cmd As String, 'command message
ByVal cmdOnly As Boolean, 'set true when command only message
ByRef rsp As String 'response message
) As Boolean 'true when response is available
Dim sdat As Byte() = New Byte(100) {}
Dim localPort As Integer = srcPort
Dim localEndPoint As System.Net.IPEndPoint = New System.Net.IPEndPoint(System.Net.IPAddress.Any, localPort)
Dim objSck As System.Net.Sockets.UdpClient = New System.Net.Sockets.UdpClient(localEndPoint)
sdat = Encoding.UTF8.GetBytes(cmd)
'Send Message as command
objSck.Send(sdat, sdat.GetLength(0), destIP, destPort)
Debug.Print("UDP packet sent From " + localEndPoint.Address.ToString + ": " + localEndPoint.Port.ToString +
" To " + destIP + ": " + destPort.ToString)
If cmdOnly = False Then
Try
'Receive Message as response
objSck.Client.ReceiveTimeout = 200 '200ms
Dim RemoteEndPoint As System.Net.IPEndPoint = New System.Net.IPEndPoint(System.Net.IPAddress.Any, 0)
Dim rdat As Byte() = objSck.Receive(RemoteEndPoint)
Dim strDT As String = Encoding.UTF8.GetString(rdat)
rsp = strDT
Debug.Print("UDP packet received From IP Adress: " + RemoteEndPoint.Address.ToString + " UDP Port:" + RemoteEndPoint.Port.ToString)
Debug.Print("Message: " + rsp)
UdpCmdRsp = True
Catch ex As Exception
UdpCmdRsp = False
End Try
Else
UdpCmdRsp = False
End If
objSck.Dispose()
End Function
Private Sub btnSend_Click(sender As Object, e As EventArgs) Handles btnSend.Click
'Send message to specified IPaddress and port
Dim strMsg As String = tbSend.Text
If rbLF.Checked Then
strMsg += vbLf
ElseIf rbCR.Checked Then
strMsg += vbCr
ElseIf rbCRLF.Checked Then
strMsg += vbCrLf
End If
Dim strRecv As String = ""
Dim strFromIP As String = ""
Dim fromPort As Integer = 0
If UdpCmdRsp(Integer.Parse(tbLocalUDP.Text),
tbIPaddress.Text,
Integer.Parse(tbUDPport.Text),
strMsg, cbCmdOnly.Checked, strRecv) Then
tbRecv.Text = strRecv
Else
tbRecv.Text = ""
End If
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim hostName As String = System.Net.Dns.GetHostName()
Dim ipAdList As System.Net.IPAddress() = System.Net.Dns.GetHostAddresses(hostName)
Dim ipA As String = ""
For Each address As System.Net.IPAddress In ipAdList
ipA = address.ToString()
Next address
Debug.Print(vbCrLf + "Host name: " + hostName + "IP Address: " + ipA)
tbLocalIP.Text = ipA
End Sub
End Class
※コメント投稿者のブログIDはブログ作成者のみに通知されます