Ahrorous
Ahrorous

Reputation: 11

How to create a webserver with soft access point in CircuitPython?

I want to serve a basic index.html file using a Raspberry Pi Pico W. I am able to in MicroPython but need to use CircuitPython for this project. I found code to create a soft access point but wasn't able to create a webserver using it:

# import wifi module
import wifi

# set access point credentials
ap_ssid = "myAP"
ap_password = "password123"

# You may also need to enable the wifi radio with wifi.radio.enabled(true)

# configure access point
wifi.radio.start_ap(ssid=ap_ssid, password=ap_password)

"""
start_ap arguments include: ssid, password, channel, authmode, and max_connections
"""

# print access point settings
print("Access point created with SSID: {}, password: {}".format(ap_ssid, ap_password))

# print IP address
print("My IP address is", wifi.radio.ipv4_address)

I tried to add a webserver:

import wifi
import socketpool

# Set access point credentials
ap_ssid = "myAP"
ap_password = "password123"

# Configure access point
wifi.radio.start_ap(ssid=ap_ssid, password=ap_password)

# Print access point settings
print("Access point created with SSID: {}, password: {}".format(ap_ssid, ap_password))
print("My IP address is", wifi.radio.ipv4_address)

# Create a socket pool
pool = socketpool.SocketPool(wifi.radio)

# Create a simple HTTP server function
def simple_http_server():
    server_socket = pool.socket()
    server_socket.bind((wifi.radio.ipv4_address, 80))
    server_socket.listen(1)

    print("Server is listening on {}:80".format(wifi.radio.ipv4_address))

    while True:
        print("Waiting for a connection...")
        client_socket, client_address = server_socket.accept()
        print("Accepted connection from:", client_address)

        client_socket.send("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n")
        client_socket.send("<html>Hello, World!</html>\r\n")
        client_socket.close()

# Start the HTTP server
simple_http_server()

I get:

Access point created with SSID: myAP, password: password123
My IP address is None
Traceback (most recent call last):
  File "<stdin>", line 36, in <module>
  File "<stdin>", line 21, in simple_http_server
TypeError: can't convert 'NoneType' object to str implicitly

Upvotes: 0

Views: 878

Answers (1)

Randint
Randint

Reputation: 73

The reason that is happening is because wifi.radio.ipv4_address only works if you connect to an existing AP. If you have your own AP, you need to use wifi.radio.ipv4_address_ap.

ipv4_address: ipaddress.IPv4Address
IP v4 Address of the station when connected to an access point. None otherwise. (read-only) ipv4_subnet_ap: ipaddress.IPv4Address
IP v4 Address of the access point subnet, when enabled. None otherwise. (read-only) https://docs.circuitpython.org/en/latest/shared-bindings/wifi/index.html#wifi.Radio

Here's the updated code:

import wifi
import socketpool

# Set access point credentials
ap_ssid = "myAP"
ap_password = "password123"

# Configure access point
wifi.radio.start_ap(ssid=ap_ssid, password=ap_password)

# Print access point settings
print("Access point created with SSID: {}, password: {}".format(ap_ssid, ap_password))
print("My IP address is", str(wifi.radio.ipv4_address_ap))

# Create a socket pool
pool = socketpool.SocketPool(wifi.radio)

# Create a simple HTTP server function
def simple_http_server():
    server_socket = pool.socket()
    server_socket.bind((str(wifi.radio.ipv4_address_ap), 80))
    server_socket.listen(1)

    print("Server is listening on {}:80".format(wifi.radio.ipv4_address))

    while True:
        print("Waiting for a connection...")
        client_socket, client_address = server_socket.accept()
        print("Accepted connection from:", client_address)

        client_socket.send("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n")
        client_socket.send("<html>Hello, World!</html>\r\n")
        client_socket.close()

# Start the HTTP server
simple_http_server()

Note: Make sure you convert wifi.radio.ipv4_address_ap into a string before using it, or you'll get this error: TypeError: can't convert 'Address' object to str implicitly

Upvotes: 3

Related Questions