No, I haven't. I'm not proficient in C, don't get on well with C programming, though I can usually get by with the sort of things I have used C for. I much prefer higher level languages which should in theory make things much easier to do.Have you ever tried to implement it in plain C instead of using micropython?
Also, switching from MicroPython to Pico SDK has in my experience been a case of exchanging one set of problems for others.
I wouldn't refuse to use C, if that's what something requires, but I can't justify the investment in figuring out 'how to' if that proves to be wasted effort with there still being problems. I'll be interested in seeing what results you get, and seeing how the code, its size and complexity, compares.
Meanwhile, back in the MicroPython arena - I wrote some tight-loop test code which is better than the framework stuff I had been using, code which ran multiple tasks and used polling or 'async'. The latest test code is at the end of this post.
Up until packets of 1,650 bytes I was seeing none dropped. After that the number of packets dropped increases. By around 2,300 as many were being dropped as received, by 2,820 more were being dropped than received, and by 6,000 about 90% were being dropped. After 7,380 the Pico W hung.
The good news is that all received, were complete and all passed verification.
I did previously see data received capped at 1024 bytes no matter how much asked for but I know that was with TCP, am not sure what I recall about UDP or if I ever checked; I quite probably had no reason to test that. Given I am receiving packets of over 7,000 bytes I am not sure why you are capped to 1,024 bytes. Perhaps different firmware, something has changed over time, or we don't have the same test environments.
Because no packets were dropped below 1,650 bytes I decided to return a reply for timing when 1,200 bytes or less. That allows the round trip time to be determined.
And I'm seeing much better turn round times than I was, under 5 ms for all which replied. So that's good news at least.
udp_size.py - For Pico W
Code:
# ***************************************************************************# * *# * Runs on the Pico W - "udp_size.py" *# * *# ***************************************************************************# * *# * Test with "python3 test_udp_size.py { <start> { <step> { <end> }}}" *# * *# ***************************************************************************UDP_PORT = 1234UDP_SIZE = 8192import networkimport socketimport timeimport secretsssid = secrets.ssidpassword = secrets.passwordprint("Running 'udp_size.py'")# .-------------------------------------------------------------------------.# | Conect to router |# `-------------------------------------------------------------------------'print("Connecting to '{}'".format(ssid))wlan = network.WLAN(network.STA_IF)wlan.active(True)wlan.config(pm=0xA11140)wlan.connect(ssid, password)while not wlan.isconnected(): print(" Waiting ...") time.sleep(1)print("Connected")# .-------------------------------------------------------------------------.# | Force Fixed IP Address of 'abc.def.ghi.199' |# `-------------------------------------------------------------------------'oldAddress, netMask, gateway, dns = wlan.ifconfig()n = oldAddress.rfind(".")newAddress = oldAddress[:n] + ".199"if oldAddress != newAddress: wlan.ifconfig((newAddress, netMask, gateway, dns))# .-------------------------------------------------------------------------.# | Show connection details |# `-------------------------------------------------------------------------'info = wlan.ifconfig()desc = ["IP Address", "Netmask", "Gateway", "DNS"]for n in range(4): print(" {:<12} : {}".format(desc[n], info[n]))# .-------------------------------------------------------------------------.# | Configure receiver |# `-------------------------------------------------------------------------'udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)udp.bind(("0.0.0.0", UDP_PORT))# .-------------------------------------------------------------------------.# | receive packets |# `-------------------------------------------------------------------------'print("Waiting for UDP packets on port {}".format(UDP_PORT))def Failed(s): print(s) while True: time.sleep(1)expectedSize = Nonewhile True: # Receive a packet payload, client = udp.recvfrom(UDP_SIZE) # If packet size was 1,200 bytes or less send a reply showing size received. # We reply as soon as we receive a packet to minimise overehead and keep # overhead of verificatio out of it. size = len(payload) if size <= 1200: udp.sendto(str(size).encode(), client) # Check for missed packets if expectedSize != None and expectedSize != size: print("Missed {} packets : ".format(size - expectedSize), end="") expectedSize = size + 1 # Report what we got print("Got {:,} bytes".format(size)) # Verify the packet txt = payload.decode() hdr = "<{}>".format(size) if not txt.startswith(hdr): Failed(" Failed start header") if not txt.endswith(hdr): Failed(" Failed end header") txt = txt[len(hdr):-len(hdr)] pad = "abcdefghijklmnopqrstuvwxyz-" while txt != "": if txt[0] != pad[0]: Failed(" Failed payload check") txt = txt[1:] pad = pad[1:] + pad[0]
Code:
#!/usr/bin/env python3# ***************************************************************************# * *# * Runs on the Pi Host - "test_udp_size.py" *# * *# ***************************************************************************# * *# * Usage "python3 test_udp_size.py { <start> { <step> { <end> }}} *# * *# ***************************************************************************import socketimport sysimport timeUDP_TARGET = "192.168.0.199"UDP_PORT = 1234if len(sys.argv) < 2 : startSize = 1000else : startSize = int(sys.argv[1])if len(sys.argv) < 3 : stepSize = 1else : stepSize = int(sys.argv[2])if len(sys.argv) < 4 : endSize = 8192else : endSize = int(sys.argv[3])# Packets in the form "<len>abcde....xyz-a<len>"skt = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)print("Starting UDP Packet Size test ...")for size in range(startSize, endSize+1, stepSize): time.sleep(1) # Build a packet to send pad = "abcdefghijklmnopqrstuvwxyz-" hdr = "<{}>".format(size) out = hdr while len(out) < (size-len(hdr)): out += pad[0] pad = pad[1:] + pad[0] out += hdr # Send the packet print("Sending {:,} bytes".format(len(out)), end ="") tx_time = time.time() skt.sendto(out.encode(), (UDP_TARGET, UDP_PORT)) # Handle reply if we sent a packet of 1200 bytes or smaller if size <= 1200: # Get a reply rxd, addr = skt.recvfrom(1024) rx_time = time.time() # Check reply is as expected if rxd.decode() != str(size): print(" - Incorrect reply {}".format(rxd)) else: # times are in seconds, convert to milliseconds elapsed = (rx_time - tx_time) * 1000 print(" - Correct reply - {:5.1f} ms round trip".format(elapsed)) else: print("")
Statistics: Posted by hippy — Sun Jul 21, 2024 3:07 pm