Circuitpython med Wiznet W5500

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
H.O
Inlägg: 5716
Blev medlem: 19 mars 2007, 10:11:27
Ort: Ronneby

Circuitpython med Wiznet W5500

Inlägg av H.O »

Jag sitter och försöker komma igång med Circuitpython på en W5500-EVB-Pico, alltså en RP2040 med påhängt W5500 Ethernet-chip.
Exempelkoden jag utgår ifrån är den här: https://github.com/Wiznet/RP2040-HAT-Ci ... oopback.py

Men, i vanlig ordning när man utgår från "exempel" så fungerar det inte. Programmet kraschar på rad 76:

Kod: Markera allt

if conn.status in (
            SNSR_SOCK_FIN_WAIT,
        ):
Med felmeddelandet: AttributeError: Objektet 'socket' har inget attribut 'status'.

Tittar jag i filen adafruit_wiznet5k_socket.py så hittar jag:

Kod: Markera allt

@property
    def _status(self) -> int:
        """
        Return the status of the socket.

        :return int: Status of the socket.
        """
        return _the_interface.socket_status(self._socknum)
Notera _socket. Om jag ändrar exempelkoden till if conn._status så fungerar DEN raden för att krasha på en annan med exakt samma problem (och potentiell lösning) men det känns inte rätt. Lite Googlande antyder att ett understreck indikerar att parametern/variabeln/funktionen är "intern" och inte avsedd att accessas "utifrån" men jag vet inte... Det känns som att socket-biblioteket ändrats/uppdaterats så den inte längre är kompatibel med exempelkoden.

Tittar man i dokumentationen för socket biblioteket så står det så här:


Skärmklipp.PNG


Så jag provade

Kod: Markera allt

if conn.socket_status in (
            SNSR_SOCK_FIN_WAIT,
        ):
Men det blir samma fel AttributeError: Objektet 'socket' har inget attribut 'socket_status'.
Finns här någon som kan förklara för mig hur det är tänkt att användas?

EDIT: Källkoden för socket-biblioteket: https://github.com/adafruit/Adafruit_Ci ... _socket.py
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
schnilsch
Inlägg: 76
Blev medlem: 11 juni 2014, 18:14:16

Re: Circuitpython med Wiznet W5500

Inlägg av schnilsch »

I klassen WIZNET5K https://github.com/adafruit/Adafruit_Ci ... iznet5k.py så finns en funktion "socket_status".

Den kräver dock att man skickar numret som socketen har (socket._socknum), så det är ju frågan hur man får tag på det utan att använda privata variabler.
H.O
Inlägg: 5716
Blev medlem: 19 mars 2007, 10:11:27
Ort: Ronneby

Re: Circuitpython med Wiznet W5500

Inlägg av H.O »

Ja jag fattar inte....
Wiznet har, på sin Github, både exempel och "kopior" av Adafruits w5k bibliotek, såväl i .py (som uppdaterats för några månader sedan) som .mpy format (tre år gammla).
Om jag använder adafruit_wiznet5k_socket.py från Wiznets Github så får jag samma fel som tidigare beträffande 'status'.
Om jag byter till den förkompilerade men äldre versionen adafruit_wiznet5k_socket.mpy så får jag istället TypeError: Objektet 'int' är inte prenumererbar.
Användarvisningsbild
rvl
Inlägg: 5817
Blev medlem: 5 april 2016, 14:58:53
Ort: Helsingfors

Re: Circuitpython med Wiznet W5500

Inlägg av rvl »

Verkar fungera för mig med en W5100-Pico, om det är samma exempelkod. Testade med Thonny.
W5100S_Pico.png
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
H.O
Inlägg: 5716
Blev medlem: 19 mars 2007, 10:11:27
Ort: Ronneby

Re: Circuitpython med Wiznet W5500

Inlägg av H.O »

Tack rvl, det var ju minst sagt intressant och tyder på att nånting är fel i min ände. Så...

Jag har (på nytt) laddat ner och på Pico'n installerat CircuitPython för W5500-EVB-Pico från https://circuitpython.org/board/wiznet_w5500_evb_pico/
Jag har laddat ner hela Github-repot från https://github.com/Wiznet/RP2040-HAT-CircuitPython
Jag har kopierat mapparna adafruit_bus_device och adafruit_wiznet5k samt filen adafruit_requests.py från det nerladdade repot till mappen lib på Pico'n.
Jag har editerar exempelkoden W5x00_Loopback.py i repot så att pinout matchar den för W5500-EVB-Pico och sparat den lokalt under namnet W5500-pico.py

Koden i sin helhet:

Kod: Markera allt

import board
import busio
import digitalio
import time
from adafruit_wiznet5k.adafruit_wiznet5k import *
import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket

#SPI0
SPI0_SCK = board.GP18
SPI0_TX = board.GP19
SPI0_RX = board.GP16
SPI0_CSn = board.GP17

#reset
W5x00_RSTn = board.GP20

print("Wiznet5k Loopback Test (DHCP)")

# Onboard LED
led = digitalio.DigitalInOut(board.GP25)
led.direction = digitalio.Direction.OUTPUT

# W5500 Reset pin
ethernetRst = digitalio.DigitalInOut(W5x00_RSTn)
ethernetRst.direction = digitalio.Direction.OUTPUT

cs = digitalio.DigitalInOut(SPI0_CSn)
spi_bus = busio.SPI(SPI0_SCK, MOSI=SPI0_TX, MISO=SPI0_RX)

# Reset W5500 first
ethernetRst.value = False
time.sleep(1)
ethernetRst.value = True

# Initialize ethernet interface with DHCP
eth = WIZNET5K(spi_bus, cs)

# Initialize a socket for our server
socket.set_interface(eth)
server = socket.socket()  # Allocate socket for the server
server_ip = None  # IP address of server
server_port = 5000  # Port to listen on
server.bind((server_ip, server_port))  # Bind to IP and Port
server.listen()  # Begin listening for incoming clients
print("server listen")

print("Chip Version:", eth.chip)
print("MAC Address:", [hex(i) for i in eth.mac_address])
print("My IP address is:", eth.pretty_ip(eth.ip_address))

conn = None

while True:
    # Maintain DHCP lease
    eth.maintain_dhcp_lease()

    if conn is None:
        conn, addr = server.accept()  # Wait for a connection from a client.
        print("socket connected!")
        print(conn, addr)
    else :
        if conn.status in (
            SNSR_SOCK_FIN_WAIT,
        ):
            print("socket SNSR_SOCK_FIN_WAIT")
            conn.close()
            conn = None
        elif conn.status in (
            SNSR_SOCK_CLOSE_WAIT,
        ):
            print("socket SNSR_SOCK_CLOSE_WAIT")
            conn.disconnect()
            conn.close()
            conn = None
        else :
            # print("socket established", conn.status)
            avail = conn.available()
            if avail:
                # print("Received size:", avail)
                # data = conn.recv(0)
                data = conn.embed_recv(2048)
                if data:
                    print("DATA ptr", id(data), ",DATA Len: ", len(data))
                    conn.send(data)  # Echo message back to client
Men när jag kör den kraschar den på rad 68 precis som innan:
Skärmklipp 2.PNG

EDIT: Jag har även provat att spara ovanstående kod PÅ Pico'n med namnet code.py och köra den men det blir samma fel.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
Icecap
Inlägg: 26151
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Circuitpython med Wiznet W5500

Inlägg av Icecap »

Har conn överhuvud en status? eller är det typ: conn.status.nåntingmer in (SNSR_SOCK_FIN_WAIT,)?

Jag ser även att du har ett komma i (SNSR_SOCK_FIN_WAIT,), är det smart?
Det vill ju ge en lista med (SNSR_SOCK_FIN_WAIT, <någonting okänd>) och det kan väl få ting o saker att skita sig.
H.O
Inlägg: 5716
Blev medlem: 19 mars 2007, 10:11:27
Ort: Ronneby

Re: Circuitpython med Wiznet W5500

Inlägg av H.O »

Jag antar att den här raden

Kod: Markera allt

conn, addr = server.accept()  # Wait for a connection from a client.
Returnerar ett objekt av typen socket (samt IP-adressen på klienten som ansluter) som får "namnet" conn. conn 'borde' då ha en status eftersom exempelkoden är skriven på det viset men uppernbarligen är det ju nått som inte fungerar riktigt.
Hurvida det är smart eller ej att ha kommatecknet där är jag inte kapabel att svara på, det är så det ser ut i exemplet. Men det gör ingen skillnad om jag tar bort det, det blir exakt samma fel.

Det som är så märkligt är att rvl fick det att funka "rakt av".
Användarvisningsbild
rvl
Inlägg: 5817
Blev medlem: 5 april 2016, 14:58:53
Ort: Helsingfors

Re: Circuitpython med Wiznet W5500

Inlägg av rvl »

Det är en tuple med ett element. Borde inte vara nåt konstigt.

Ja, lite märkligt även om jag har litet annan hårdvara.
H.O
Inlägg: 5716
Blev medlem: 19 mars 2007, 10:11:27
Ort: Ronneby

Re: Circuitpython med Wiznet W5500

Inlägg av H.O »

Nej hårdvaran BORDE inte spela någon roll i det här fallet. Om jag läser koden rätt så är det i slutänden socketens statusregister i W5x00 som (ska) returneras men i det här fallet så verkar den ju liksom inte komma till att ens försöka läsa hårdvaran (i så fall skulle den kunna läsa fel register på W5500 men rätt på W5100). Men som sagt, min begränsade kunskap säger att så inte är fallet.

rvl,
Skulle du möjligen kunna zippa ihop det som ligger på din Pico när det fungerar hos dig så jag kan testa EXAKT samma som du har.
Mr Andersson
Inlägg: 1397
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Circuitpython med Wiznet W5500

Inlägg av Mr Andersson »

2023-02-22 bytte de namn på status till _status men jag ser ingen direkt förklaring till varför. Commit-meddelandet är bara "Updated to latest version of socket.py"
Koden i funktionen är oförändrad så jag skulle säga att skit i att den är "privat" och använd den ändå. (eller byt till en äldre version)
Användarvisningsbild
rvl
Inlägg: 5817
Blev medlem: 5 april 2016, 14:58:53
Ort: Helsingfors

Re: Circuitpython med Wiznet W5500

Inlägg av rvl »

Ska jag väl kunna göra när jag plockar fram modulen. "Exakt samma" förutom hårdvarupinnumren då, men det har du ju koll på annars hade inte koden kommit så långt, innan det blev felmeddelande ...på svenska. :shock:
H.O
Inlägg: 5716
Blev medlem: 19 mars 2007, 10:11:27
Ort: Ronneby

Re: Circuitpython med Wiznet W5500

Inlägg av H.O »

rvl, jag tackar för det om/när du har möjlighet.
Det visar sig att pin-outen för W5100-EVB-Pico som du har och W5500-EVB-Pico som jag har ÄR exakt samma så i praktiken ändrade jag inget...
Svenska blev det "by default" när jag laddade ner CircuitPython men jag har laddat ner engelsk version och provat med också - samma fel (inte oväntat).

MrAndersson,
Tack för den djupdykningen i historiken.
Hade det bara varit just .status så hade jag bara kört på det som fungerar men de måste ju typ ändrat på hela API-funktionaliteten eftersom den kraschar på fler ställen med samma fel (och lösning). Frågan är hur det är menat att användas.
Jag är ingen fena på Python och att då försöka lära sig av exempel som inte fungerar och från dokumentation man inte är säker på är aktuell gör inte saken enklare :-)
Användarvisningsbild
rvl
Inlägg: 5817
Blev medlem: 5 april 2016, 14:58:53
Ort: Helsingfors

Re: Circuitpython med Wiznet W5500

Inlägg av rvl »

Jag hade äldre versioner av Thonny, Circuit python och biblioteket.

Som Mr Andersson säger så har status blivit _status och även några andra funktioner har fått ett inledande understreck.
Det här fungerar med nya versionerna.

Kod: Markera allt

import board
import busio
import digitalio
import time
from adafruit_wiznet5k.adafruit_wiznet5k import *
import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket

##SPI0
SPI0_SCK = board.GP18
SPI0_TX = board.GP19
SPI0_RX = board.GP16
SPI0_CSn = board.GP17

##reset
W5x00_RSTn = board.GP20

print("Wiznet5k Loopback Test (DHCP)")
# Setup your network configuration below
# random MAC, later should change this value on your vendor ID
MY_MAC = (0x00, 0x01, 0x02, 0x03, 0x04, 0x05)
IP_ADDRESS = (192, 168, 1, 100)
SUBNET_MASK = (255, 255, 255, 0)
GATEWAY_ADDRESS = (192, 168, 1, 1)
DNS_SERVER = (8, 8, 8, 8)

led = digitalio.DigitalInOut(board.GP25)
led.direction = digitalio.Direction.OUTPUT

ethernetRst = digitalio.DigitalInOut(W5x00_RSTn)
ethernetRst.direction = digitalio.Direction.OUTPUT

# For Adafruit Ethernet FeatherWing
cs = digitalio.DigitalInOut(SPI0_CSn)
# For Particle Ethernet FeatherWing
# cs = digitalio.DigitalInOut(board.D5)

spi_bus = busio.SPI(SPI0_SCK, MOSI=SPI0_TX, MISO=SPI0_RX)

# Reset W5x00 first
ethernetRst.value = False
time.sleep(1)
ethernetRst.value = True

# # Initialize ethernet interface without DHCP
# eth = WIZNET5K(spi_bus, cs, is_dhcp=False, mac=MY_MAC, debug=False)
# # Set network configuration
# eth.ifconfig = (IP_ADDRESS, SUBNET_MASK, GATEWAY_ADDRESS, DNS_SERVER)

# Initialize ethernet interface with DHCP
eth = WIZNET5K(spi_bus, cs, is_dhcp=True, mac=MY_MAC, debug=False)

# Initialize a socket for our server
socket.set_interface(eth)
server = socket.socket()  # Allocate socket for the server
server_ip = None  # IP address of server
server_port = 5000  # Port to listen on
server.bind((server_ip, server_port))  # Bind to IP and Port
server.listen()  # Begin listening for incoming clients
print("server listen")

print("Chip Version:", eth.chip)
print("MAC Address:", [hex(i) for i in eth.mac_address])
print("My IP address is:", eth.pretty_ip(eth.ip_address))

conn = None

while True:
    # Maintain DHCP lease
    eth.maintain_dhcp_lease()

    if conn is None:
        conn, addr = server.accept()  # Wait for a connection from a client.
        print("socket connected")
        print(conn, addr)
    else :
        if conn._status in (
            SNSR_SOCK_FIN_WAIT,
        ):
            print("socket SNSR_SOCK_FIN_WAIT")
            conn.close()
            conn = None
        elif conn._status in (
            SNSR_SOCK_CLOSE_WAIT,
        ):
            print("socket SNSR_SOCK_CLOSE_WAIT")
            conn._disconnect()
            conn.close()
            conn = None
        else :
            # print("socket established", conn.status)
            avail = conn._available()
            if avail:
                # print("Received size:", avail)
                # data = conn.recv(0)
                data = conn._embed_recv(2048)
                if data:
                    print("DATA ptr", id(data), ",DATA Len: ", len(data))
                    conn.send(data)  # Echo message back to client
Användarvisningsbild
rvl
Inlägg: 5817
Blev medlem: 5 april 2016, 14:58:53
Ort: Helsingfors

Re: Circuitpython med Wiznet W5500

Inlägg av rvl »

Och den utlovade zipen, som inte längre borde vara intressant eftersom den kräver en äldre version (7.2.5 hade jag) av circuitpython.

Testprogram för datorn:

Kod: Markera allt

import socket

HOST = "192.168.0.15"  # The server's hostname or IP address
PORT = 5000  # The port used by the server

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))
    s.sendall(b"Hello, EF")
    data = s.recv(1024)

print(f"Received {data!r}")
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
H.O
Inlägg: 5716
Blev medlem: 19 mars 2007, 10:11:27
Ort: Ronneby

Re: Circuitpython med Wiznet W5500

Inlägg av H.O »

Tack rvl, jo det där med understrecken hade jag ju listat ut men misstänker som sagt att det finns nån anledning till att man ändrat och/eller att det nu finns ett bättre/korrekt sätt att komma åt samma funktionalitet.
Men, strunt samma, jag petar dit ett understreck framför berörda funktioner etc och leker vidare.

Kan tillägga att jag ställt frågan på såväl Wiznet's som Adafruit/CircuitPython forum utan att få något som helst svar. Hatten av EF.
Skriv svar