-
-
Save todbot/877b2037b6c7b2c4c11545c83c6e2182 to your computer and use it in GitHub Desktop.
# udp_recv_code.py -- receive UDP messages from any receiver, can be another CircuitPython device | |
# 24 Aug 2022 - @todbot / Tod Kurt | |
# cribbing from code at https://github.com/adafruit/circuitpython/blob/main/tests/circuitpython-manual/socketpool/datagram/ntp.py | |
import time, wifi, socketpool | |
from secrets import secrets | |
print("Connecting to WiFi...") | |
wifi.radio.connect(ssid=secrets['ssid'],password=secrets['password']) | |
print("my IP addr:", wifi.radio.ipv4_address) | |
pool = socketpool.SocketPool(wifi.radio) | |
udp_host = str(wifi.radio.ipv4_address) # my LAN IP as a string | |
udp_port = 5005 # a number of your choosing, should be 1024-65000 | |
udp_buffer = bytearray(64) # stores our incoming packet | |
sock = pool.socket(pool.AF_INET, pool.SOCK_DGRAM) # UDP socket | |
sock.bind((udp_host, udp_port)) # say we want to listen on this host,port | |
print("waiting for packets on",udp_host, udp_port) | |
while True: | |
size, addr = sock.recvfrom_into(udp_buffer) | |
msg = udp_buffer.decode('utf-8') # assume a string, so convert from bytearray | |
print(f"Received message from {addr[0]}:", msg) |
# udp_send_code.py -- send UDP messages to specified receiver, can be another CircuitPython device | |
# 24 Aug 2022 - @todbot / Tod Kurt | |
# cribbing from code at https://github.com/adafruit/circuitpython/blob/main/tests/circuitpython-manual/socketpool/datagram/ntp.py | |
import time, wifi, socketpool | |
from secrets import secrets | |
print("Connecting to WiFi...") | |
wifi.radio.connect(ssid=secrets['ssid'],password=secrets['password']) | |
print("my IP addr:", wifi.radio.ipv4_address) | |
pool = socketpool.SocketPool(wifi.radio) | |
udp_host = "192.168.1.123" # LAN IP of UDP receiver | |
udp_port = 5005 # must match receiver! | |
my_message = "hi there from CircuitPython!" | |
sock = pool.socket(pool.AF_INET, pool.SOCK_DGRAM) # UDP, and we'l reuse it each time | |
num = 0 | |
while True: | |
# stick a nubmer on the end of the message to show progress and conver to bytearray | |
udp_message = bytes(f"{my_message} {num}", 'utf-8') | |
num += 1 | |
print(f"Sending to {udp_host}:{udp_port} message:", udp_message) | |
sock.sendto(udp_message, (udp_host,udp_port) ) # send UDP packet to udp_host:port | |
time.sleep(1) |
I used your receiver example (only modified to use settings.toml instead of the former secrets.py.
Script used:
# udp_recv_code.py -- receive UDP messages from any receiver, can be another CircuitPython device
# 24 Aug 2022 - @todbot / Tod Kurt
# cribbing from code at https://github.com/adafruit/circuitpython/blob/main/tests/circuitpython-manual/socketpool/datagram/ntp.py
import time, wifi, socketpool, os
print("Connecting to WiFi...")
wifi.radio.connect(ssid=os.getenv("CIRCUITPY_WIFI_SSID"), password=os.getenv("CIRCUITPY_WIFI_PASSWORD"))
print("my IP addr:", wifi.radio.ipv4_address)
pool = socketpool.SocketPool(wifi.radio)
# I, @PaulskPt, used for udp_host erroneously: os.getenv("MULTICAST_GROUP")
udp_host = str(wifi.radio.ipv4_address) # my LAN IP as a string
udp_port = int(os.getenv("MULTICAST_PORT")) # a number of your choosing, should be 1024-65000
udp_buffer = bytearray(64) # stores our incoming packet
sock = pool.socket(pool.AF_INET, pool.SOCK_DGRAM) # UDP socket
sock.bind((udp_host, udp_port)) # say we want to listen on this host,port
print("waiting for packets on",udp_host, udp_port)
while True:
size, addr = sock.recvfrom_into(udp_buffer)
msg = udp_buffer.decode('utf-8') # assume a string, so convert from bytearray
print(f"Received message from {addr[0]}:", msg)
Resulting in the following output:
Received message from 192.168.1.96: XATT2,148.0,5.9,0.5,-0.0000,0.0000,-0.0000,0.0,-0.0,-0.0,-0.01,0
Received message from 192.168.1.96: XATT2,148.0,5.9,0.5,-0.0000,0.0000,-0.0000,0.0,-0.0,-0.0,-0.01,0
Received message from 192.168.1.96: XATT2,148.0,5.9,0.5,-0.0000,0.0000,-0.0000,0.0,-0.0,-0.0,-0.01,0
Received message from 192.168.1.96: XATT2,148.0,5.9,0.5,-0.0000,0.0000,-0.0000,0.0,-0.0,-0.0,-0.01,0
Received message from 192.168.1.96: XGPS2,-85.700840,38.354860,156.1102,147.9949,0.0001,-0.0,-0.01,0
Received message from 192.168.1.96: XATT2,148.0,5.9,0.5,-0.0000,0.0000,-0.0000,0.0,-0.0,-0.0,-0.01,0
Received message from 192.168.1.96: XATT2,148.0,5.9,0.5,-0.0000,0.0000,-0.0000,0.0,-0.0,-0.0,-0.01,0
Received message from 192.168.1.96: XATT2,148.0,5.9,0.5,-0.0000,0.0000,-0.0000,0.0,-0.0,-0.0,-0.01,0
Received message from 192.168.1.96: XATT2,148.0,5.9,0.5,-0.0000,0.0000,-0.0000,0.0,-0.0,-0.0,-0.01,0
Received message from 192.168.1.96: XATT2,148.0,5.9,0.5,-0.0000,0.0000,-0.0000,0.0,-0.0,-0.0,-0.01,0
Received message from 192.168.1.96: XATT2,148.0,5.9,0.5,-0.0000,0.0000,-0.0000,0.0,-0.0,-0.0,-0.01,0
Received message from 192.168.1.96: XATT2,148.0,5.9,0.5,-0.0000,0.0000,-0.0000,0.0,-0.0,-0.0,-0.01,0
Received message from 192.168.1.96: XATT2,148.0,5.9,0.5,-0.0000,0.0000,-0.0000,0.0,-0.0,-0.0,-0.01,0
Received message from 192.168.1.96: XATT2,148.0,5.9,0.5,-0.0000,0.0000,-0.0000,0.0,-0.0,-0.0,-0.01,0
Btw: the data is from a situation when the airplane was on the ground, parked. Engine running.
There is no packet reception when I use port 49707 or 49003 instead of port 49002.
Port 49707 is used for UDP datagrams (BECN and DATA packets) to Multicast group '169.255.1.1'. The DATA packets contain
data elements that I selected inside the X-Plane 12 setup
Update:
I receive the DATA packets when I enter in X-Plane settings for 'General Data Output' IP Address, the IP address: 192.168.1.110, which is the IP Address of the CPY device running the script, and Port 49707. But I get a 'UnicodeError' because the received UDP packets are packed.
When I modify the line 'msg = udp_buffer.decode('utf-8')' into: 'msg = udp.buffer' then the following output is received (only one packet copied below):
Received message from 192.168.1.96: bytearray(b'DATA*\x03\x00\x00\x00\x00\x00\x00\x00:\xb9\x989\xa9\xdf\x999\xd5E\x979\x00\xc0y\xc4\x00\x00\x00\x00\x1d\x13\xb19\xe5\x14\xae9\x11\x00\x00\x00e\xc6\xbc@8\xb5\t?\x1e\xff\x13C\x00\xc0y\xc4\xcb\x10\x19')
So, I think my problem is solved!
Again thank you for your rapid responses!
Thanks, this is very helpful!
By the way, line 22 of udp_recv_code.py
msg = udp_buffer.decode('utf-8')
should be
msg = udp_buffer[:size].decode('utf-8')
or otherwise you might print unwanted things:)
@aceg00 thank you for your response and advice.
OK, I'll will use a simple script to test. I already set port triggers in the router of my ISP. In the MS Windows 11 desktop PC running the X-Plane flight simulator I created UDP input/output rules for the ports needed in the Defender Firewall.