M5Stack LAN BASE trying to be a web server with Micropython



  • I hope someone has achieved this and can point me in the right direction.

    I have an M5 with the W5500 LAN base and am trying to have it run just a simple web form to turn a couple of ports on or off. The code below works fine if I use WiFi, but just hangs at the 'conn, addr = s.accept()' command when I used the wired LAN connection. I am getting an IP address and I can ping it, but when I try and browse to it I get a 'connection refused' error.

    Help!

    Here is the code:

    from m5stack import *
    from m5ui import *
    from uiflow import *
    import module
    import network
    import socket

    lcd.clear()

    lan = module.get(module.LANBASE)
    eth0Ip = lan.get_if_config()[0]
    label1 = M5TextBox(10, 10, "Eth0 ip :" + str(eth0Ip), lcd.FONT_Ubuntu, 0xfff500, rotate=0)
    #lan.tcp_udp_config(eth0Ip, 80, 1, 1)
    #label2 = M5TextBox(10, 25, "UDP configured", lcd.FONT_Ubuntu, 0xfff500, rotate=0)

    Setup GPIO

    pin1 = machine.Pin(5, machine.Pin.OUT)
    pin2 = machine.Pin(2, machine.Pin.OUT)

    def generate_html():
    # Generate HTML based on GPIO states
    state1 = "Power is open - Click to close" if pin1.value() else "Power is closed - click to open"
    state2 = "Reset is open - Click to close" if pin2.value() else "Reset is closed - click to open"

    html = """<!DOCTYPE html>
    <html>
    <head> <title>Remote Reset and Power Control</title> </head>
    <body> <h1>Remote Reset and Power Control</h1>
      <button onclick="toggleGPIO(1)">{state1}</button><br>
      <button onclick="toggleGPIO(2)">{state2}</button><br>
      <script>
      function toggleGPIO(gpio) {{
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function() {{
          if (this.readyState == 4 && this.status == 200) {{
            window.location.reload(); // Reload the page
          }}
        }};
        xhr.open('GET', '/toggle?gpio=' + gpio, true);
        xhr.send();
      }}
      </script>
    </body>
    </html>
    """
    return html
    

    HTTP response

    def http_response(status, content_type, body):
    return 'HTTP/1.1 {} OK\r\nContent-Type: {}\r\n\r\n{}'.format(status, content_type, body)

    Handle HTTP requests

    def handle_http_request(conn):
    request = conn.recv(1024)
    request = str(request)
    #print('Content = %s' % request)
    gpio = request.find('/toggle?gpio=')
    if gpio == 6:
    gpio_number = int(request[19])
    if gpio_number == 1:
    pin1.value(not pin1.value())
    elif gpio_number == 2:
    pin2.value(not pin2.value())

    response = generate_html()
    conn.sendall(http_response(200, "text/html", response))
    conn.close()
    

    Main loop

    addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]

    #s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # This was something that ChatGPT suggested - made no difference
    s = socket.socket()
    s.bind(addr)
    s.listen(1)

    label2 = M5TextBox(10, 40, "Listening on :" + str(addr), lcd.FONT_Ubuntu, 0xfff500, rotate=0)

    while True:
    try:
    label2 = M5TextBox(10,90, "Working...", lcd.FONT_Ubuntu, 0xfff500, rotate=0)
    conn, addr = s.accept()
    label2 = M5TextBox(10, 70, "Connection from :" + str(addr), lcd.FONT_Ubuntu, 0xfff500, rotate=0)
    handle_http_request(conn)
    except OSError as e:
    conn.close()
    label2 = M5TextBox(10, 70, "Connection closed :" + str(addr), lcd.FONT_Ubuntu, 0xfff500, rotate=0)

    END