[Python] W5500-EVB-PICO (RP2040) alwas comes back with "Socket operation failed: [Errno 107]...

Discussão em 'Python' iniciado por Stack, Abril 3, 2025.

  1. Stack

    Stack Membro Participativo

    I am using W5500-EVB-PICO to connect via Ethernet to the network. Later I want to send out BME680 data to Thingspeak. Whatever I try, I always get "Socket operation failed: [Errno 107] ENOTCONN". I am trying firmware rp2_w5500_20220318_v1.04.uf2, rp2_w5500_20220421_v1.0.5.uf2 and rp2_w5500_20221111_v2.0.0.uf2.

    Does someone know the issue and might help with some good solutions?

    This is my code, I hope it did copy flawlessly into here.

    MAIN2.py

    from machine import Pin, SPI, I2C
    import network
    import time
    import socket
    from bme680 import BME680_I2C

    #Global network interface
    nic = None

    #ThingSpeak configuration
    THINGSPEAK_API_KEY = "XXXXXXXXXXXXXXXXX"

    #Pin definitions

    LED_PIN = 25
    I2C_SDA_PIN = 2
    I2C_SCL_PIN = 3
    SPI_MOSI_PIN = 19
    SPI_MISO_PIN = 16
    SPI_SCK_PIN = 18
    SPI_CS_PIN = 17
    RESET_PIN = 20

    #Initialize LED
    led = Pin(LED_PIN, Pin.OUT)

    #Initialize I2C and BME680
    i2c = I2C(1, sda=Pin(I2C_SDA_PIN), scl=Pin(I2C_SCL_PIN), freq=400000)
    bme = BME680_I2C(i2c, debug=True)

    def send_to_thingspeak(temp, humid, press):
    """Send data to ThingSpeak using network interface directly"""
    global nic
    try:
    print("\nPreparing to send data...")


    # Reset network interface
    print("Resetting network interface...")
    nic.active(False)
    time.sleep(2)
    nic.active(True)
    time.sleep(5)

    # Wait for connection
    print("Waiting for connection...")
    for i in range(15): # Longer timeout
    if nic.isconnected():
    break
    print(".", end="")
    time.sleep(1)
    print()

    # Check network status
    print("Checking network status...")
    print("Network connected:", nic.isconnected())
    config = nic.ifconfig()
    print("Current network configuration:")
    print("IP:", config[0])
    print("Gateway:", config[2])

    if not nic.isconnected() or config[0] == '0.0.0.0':
    raise Exception("Network not properly connected")

    # Format the data string
    print("Formatting request data...")
    data = "field1={}&field2={}&field3={}".format(temp, humid, press)

    # Prepare the HTTP request (simplified)
    print("Preparing HTTP request...")
    request = (
    "GET /update?api_key={}&{} HTTP/1.0\r\n"
    "Host: api.thingspeak.com\r\n"
    "Connection: close\r\n"
    "\r\n"
    ).format(THINGSPEAK_API_KEY, data)
    print("Request:", request)

    # Create socket
    print("Creating socket...")
    sock = None

    try:
    # Try with direct IP
    server_ip = "184.106.153.149" # ThingSpeak IP
    print(f"Connecting to {server_ip}:80...")

    sock = socket.socket()
    sock.settimeout(10)

    # Try to connect
    print("Attempting connection...")
    sock.connect((server_ip, 80))
    print("Connected!")

    # Send data in small chunks
    print("Sending data...")
    request_bytes = request.encode()
    chunk_size = 64
    for i in range(0, len(request_bytes), chunk_size):
    chunk = request_bytes[i:i + chunk_size]
    print(f"Sending chunk {i//chunk_size + 1}...")
    sock.send(chunk)
    time.sleep(0.1) # Small delay between chunks

    # Read response
    print("Reading response...")
    response = b""
    while True:
    try:
    chunk = sock.recv(64) # Small chunks
    if not chunk:
    break
    response += chunk
    if b"\r\n\r\n" in response: # Found end of headers
    break
    except socket.timeout:
    break

    response_str = response.decode()
    print("Response:", response_str)

    if "200 OK" in response_str:
    print("Upload successful!")
    return True
    else:
    print("Upload failed - bad response")
    return False

    except Exception as e:
    print("Socket operation failed:", str(e))
    print("Exception type:", type(e))
    return False

    finally:
    if sock:
    try:
    sock.close()
    except:
    pass

    except Exception as e:
    print("Error in send_to_thingspeak:", str(e))
    print("Exception type:", type(e))
    return False

    def init_ethernet():"""Initialize W5500 Ethernet connection"""
    global nic
    print("\nInitializing Ethernet...")
    led.value(0)

    try:
    # Initialize SPI for W5500
    spi = SPI(0,
    baudrate=500_000,
    mosi=Pin(SPI_MOSI_PIN),
    miso=Pin(SPI_MISO_PIN),
    sck=Pin(SPI_SCK_PIN))

    # Initialize CS and Reset pins
    cs = Pin(SPI_CS_PIN, Pin.OUT)
    reset = Pin(RESET_PIN, Pin.OUT)

    # Hard reset sequence
    print("Hard reset sequence...")
    cs.value(1) # Ensure CS is high
    reset.value(1) # Reset high
    time.sleep(1.0) # Wait
    reset.value(0) # Reset low
    time.sleep(1.0) # Hold in reset
    reset.value(1) # Reset high
    time.sleep(2.0) # Longer wait for chip to start

    # Initialize WIZNET5K
    print("Initializing network interface...")
    nic = network.WIZNET5K(spi, cs, reset)
    time.sleep(1.0) # Wait after initialization

    # Configure network using DHCP
    print("Configuring network via DHCP...")
    nic.active(True)
    time.sleep(5.0) # Wait for DHCP

    # Wait for network configuration
    print("Waiting for network configuration...")
    for i in range(20): # 20 second timeout
    if nic.isconnected() and nic.ifconfig()[0] != '0.0.0.0':
    break
    print(".", end="")
    time.sleep(1)
    print()

    # Get and verify configuration
    config = nic.ifconfig()
    print('\nNetwork Configuration:')
    print('IP :', config[0])
    print('Gateway :', config[2])

    if not nic.isconnected() or config[0] == '0.0.0.0':
    raise Exception("Failed to establish network connection")

    # Additional wait for network stack
    print("Waiting for network stack to initialize...")
    time.sleep(5) # Reduced wait time

    led.value(1)
    return nic

    except Exception as e:
    print("Error initializing ethernet:", e)
    led.value(0)
    raise

    def read_sensor():
    """Read BME680 sensor data"""
    try:
    temperature = round(bme.temperature - 4, 2)
    humidity = round(bme.humidity + 14, 2)
    pressure = round(bme.pressure, 2)

    print('\nSensor Readings:')
    print('Temperature: {}°C'.format(temperature))
    print('Humidity: {}%'.format(humidity))
    print('Pressure: {}mbar'.format(pressure))
    print('-------')

    return temperature, humidity, pressure

    except Exception as e:
    print("Error reading sensor:", e)
    raise

    def main():
    global nic
    retry_count = 0
    max_retries = 3

    while True:
    try:
    if retry_count >= max_retries:
    print("Maximum retries reached, resetting device...")
    machine.reset()

    nic = init_ethernet()
    retry_count = 0

    while True:
    try:
    temp, humid, press = read_sensor()

    if send_to_thingspeak(temp, humid, press):
    led.value(1)
    time.sleep(15) # Wait between uploads
    else:
    raise Exception("Failed to send data")

    except Exception as e:
    print("Error in measurement loop:", e)
    raise

    except Exception as e:
    print("Error in main loop:", e)
    led.value(0)
    retry_count += 1
    time.sleep(5 * retry_count)

    if name == "main":main()


    UREQUESTS

    import usocket

    class Response:
    def init(self, f):
    self.raw = f
    self.encoding = "utf-8"
    self._cached = None

    def close(self):
    if self.raw:
    self.raw.close()
    self.raw = None
    self._cached = None

    @property
    def content(self):
    if self._cached is None:
    try:
    self._cached = self.raw.read()
    finally:
    self.raw.close()
    self.raw = None
    return self._cached

    @property
    def text(self):
    return str(self.content, self.encoding)

    def json(self):
    import ujson

    return ujson.loads(self.content)

    def request(
    method,
    url,
    data=None,
    json=None,
    headers={},
    stream=None,
    auth=None,
    timeout=None,
    parse_headers=True,
    ):
    redirect = None # redirection url, None means no redirection
    chunked_data = data and getattr(data, "iter", None) and not getattr(data, "len", None)

    if auth is not None:
    import ubinascii

    username, password = auth
    formated = b"{}:{}".format(username, password)
    formated = str(ubinascii.b2a_base64(formated)[:-1], "ascii")
    headers["Authorization"] = "Basic {}".format(formated)

    try:
    proto, dummy, host, path = url.split("/", 3)
    except ValueError:
    proto, dummy, host = url.split("/", 2)
    path = ""
    if proto == "http:":
    port = 80
    elif proto == "https:":
    import ussl

    port = 443
    else:
    raise ValueError("Unsupported protocol: " + proto)

    if ":" in host:
    host, port = host.split(":", 1)
    port = int(port)

    ai = usocket.getaddrinfo(host, port, 0, usocket.SOCK_STREAM)
    ai = ai[0]

    resp_d = None
    if parse_headers is not False:
    resp_d = {}

    s = usocket.socket(ai[0], usocket.SOCK_STREAM, ai[2])

    if timeout is not None:
    # Note: settimeout is not supported on all platforms, will raise
    # an AttributeError if not available.
    s.settimeout(timeout)

    try:
    s.connect(ai[-1])
    if proto == "https:":
    s = ussl.wrap_socket(s, server_hostname=host)
    s.write(b"%s /%s HTTP/1.0\r\n" % (method, path))
    if not "Host" in headers:
    s.write(b"Host: %s\r\n" % host)
    # Iterate over keys to avoid tuple alloc
    for k in headers:
    s.write(k)
    s.write(b": ")
    s.write(headers[k])
    s.write(b"\r\n")
    if json is not None:
    assert data is None
    import ujson

    data = ujson.dumps(json)
    s.write(b"Content-Type: application/json\r\n")
    if data:
    if chunked_data:
    s.write(b"Transfer-Encoding: chunked\r\n")
    else:
    s.write(b"Content-Length: %d\r\n" % len(data))
    s.write(b"Connection: close\r\n\r\n")
    if data:
    if chunked_data:
    for chunk in data:
    s.write(b"%x\r\n" % len(chunk))
    s.write(chunk)
    s.write(b"\r\n")
    s.write("0\r\n\r\n")
    else:
    s.write(data)

    l = s.readline()
    # print(l)
    l = l.split(None, 2)
    if len(l) < 2:
    # Invalid response
    raise ValueError("HTTP error: BadStatusLine:\n%s" % l)
    status = int(l[1])
    reason = ""
    if len(l) > 2:
    reason = l[2].rstrip()
    while True:
    l = s.readline()
    if not l or l == b"\r\n":
    break
    # print(l)
    if l.startswith(b"Transfer-Encoding:"):
    if b"chunked" in l:
    raise ValueError("Unsupported " + str(l, "utf-8"))
    elif l.startswith(b"Location:") and not 200 <= status <= 299:
    if status in [301, 302, 303, 307, 308]:
    redirect = str(l[10:-2], "utf-8")
    else:
    raise NotImplementedError("Redirect %d not yet supported" % status)
    if parse_headers is False:
    pass
    elif parse_headers is True:
    l = str(l, "utf-8")
    k, v = l.split(":", 1)
    resp_d[k] = v.strip()
    else:
    parse_headers(l, resp_d)
    except OSError:
    s.close()
    raise

    if redirect:
    s.close()
    if status in [301, 302, 303]:
    return request("GET", redirect, None, None, headers, stream)
    else:
    return request(method, redirect, data, json, headers, stream)
    else:
    resp = Response(s)
    resp.status_code = status
    resp.reason = reason
    if resp_d is not None:
    resp.headers = resp_d
    return resp

    def head(url, **kw):return request("HEAD", url, **kw

    def get(url, **kw):return request("GET", url, **kw

    def post(url, **kw):return request("POST", url, **kw

    def put(url, **kw):return request("PUT", url, **kw)

    def patch(url, **kw):return request("PATCH", url, **kw)

    def delete(url, **kw):return request("DELETE", url, **kw)

    Continue reading...

Compartilhe esta Página