Skip to content

W5500-EVB-PICO - Unexplained TCP & UDP Transfer Speed Delays and Variations...Very Slow #15645

@BB486999

Description

@BB486999

Port, board and/or hardware

W5500-EVB-PICO

MicroPython version

MicroPython v1.23.0 on 2024-06-02; W5500-EVB-Pico with RP2040

Reproduction

Master Code running on a PC:

import socket
import time
import os
import math


MCAST_GROUP = '224.1.1.1'
MCAST_PORT = 5007
MASTER_PORT = 5008
CAST_ADDR = '255.255.255.255'


def create_master():
    #?Create a UDP socket for broadcasting
    sock_broadcast = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    sock_broadcast.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock_broadcast.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    #sock_broadcast.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 8)
    #sock_broadcast.bind(('', 5007))

    #?Create a UDP socket for receiving responses
    sock_receive = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock_receive.bind(('', MASTER_PORT))
    sock_receive.setblocking(0)

    return sock_broadcast, sock_receive



def run_master(sock_broadcast, sock_receive):

    while True:

        sock_receive.settimeout(2)
        start_time = time.time()

        for i in range(100):
            sock_broadcast.sendto("SPEED TEST.........................................................................................".encode(), (CAST_ADDR, 5007))
            data, addr = sock_receive.recvfrom(1024)
            print("Iteration: ", i, " - ", round(((time.time() - start_time) / (i + 1)), 5), " s")
        end_time = time.time()


        if data:
            print(f"Master received: {data.decode()} from {addr}")
            print("Elapsed time: ", ((end_time - start_time)))
            print("Average round trip per message: ", ((end_time - start_time) / 100))

        break


sock_broadcast_master, sock_receive_master = create_master()
run_master(sock_broadcast_master, sock_receive_master)

Slave Code on the W5500-EVB-PICO

#pylint: skip-file
import wiznet_w5500.w5500 as w5500
import usocket as socket
from machine import Pin
import utime as time
import gc

led = Pin(25, Pin.OUT)

gc.collect()

#Note, switched to static
w5500.w5500_init_dhcp()


led.value(1)

#Create the listener socket
listener_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#listener_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

listener_socket.bind(('224.1.1.1', 5007))


#Create the responder

send_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

start_time = time.time()

while True:
    data, addr = listener_socket.recvfrom(1024)
    print("Data: ", data, " from addr: ", addr)
    listener_socket.sendto("SPEED TEST RETURN".encode(), ('255.255.255.255', 5008))

print("Finished")

And corresponding w5500 library for reference:

#SPI SETUP for onboard WizNET chip
MOSI = Pin(19)
MISO = Pin(16)
SCK = Pin(18)
CS = Pin(17)
RST = Pin(20)


#W5500 onboard chip initialization
def w5500_init_dhcp():
    spi=SPI(0,60_000_000, mosi=MOSI,miso=MISO,sck=SCK)
    print(spi)

    nic = network.WIZNET5K(spi,CS,RST) # type: ignore #spi,cs,reset pin


    nic.active(True)

    #It looks like we have a mac address...
    mac = nic.config('mac')
    print("''''''''''''''''''''''''''")
    print("MAC ADDR: -> ", ':'.join('{:02x}'.format(mac[i]) for i in range(6)))



    #nic.ifconfig('dhcp')
    nic.ifconfig(('168.5.0.12', '255.255.0.0', '0.0.0.0', '0.0.0.0'))
    print('\nAssigned IP address: -> ', nic.ifconfig()[0], "\nSubnet Mask: -> ", nic.ifconfig()[1], "\nGateway: -> ", nic.ifconfig()[2], "\nDNS: -> ", nic.ifconfig()[3])
    print("''''''''''''''''''''''''''\n\n")

    #while not nic.isconnected():
        #time.sleep(1)
        #print("Waiting...")
        #print(nic.regs())

When running the following code (round trip UDP messages, one down to slave, one back up to master) with MicroPython official release 1.23.0, I get about 65 ms round trip per message.

When running with WizNet's own v2.0.0 release on their website (https://github.com/Wiznet/RP2040-HAT-MicroPython/releases), I am looking at around 2-5ms per message. Note that this is roughly in the same range if I ran the master and slave code on two separate PCs with the same setup (2-5 ms per message).

I don't want to have to use the WizNet micropython build because it is incredibly unstable (print statements are delayed, misses keyboard interrupts when stopping, lacking many features/functions, etc.), but I really need the speed for my application. Why is the MicroPython build so much slower, is this a bug that can be addressed? Thanks

Expected behaviour

Micropython Official 1.23.0 build UDP back and forth: ~ 65 ms
WizNet v2.0.0 Micropython build UDP back and forth: ~ 2-5 ms
PC to PC UDP back and forth: ~ 2 ms

Expected is micropython official build to be ~ 2-5 ms

Observed behaviour

Micropython build is significantly slower sending UDP messages (tens of milliseconds slower) than using WizNet's v2.0.0 build or compared to PC to PC UDP messaging.

PC to PC: ~2 ms
PC to Wiznet v2.0.0 micropython w5500-EVB-PICO: ~2-5 ms
PC to Micropython v1.23.0 build W5500-EVB-PICO: ~65 ms +

Additional Information

No, I've provided everything above.

Code of Conduct

Yes, I agree

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions