esp32之micropython 配網程式碼

misskiki發表於2024-09-16

esp32之micropython 配網程式碼

最近學習esp32的時候想著能不能給裝置自動配網,查了下網上有smartconfig配網但是我無法配置成功所以自己寫了AP配網。

AP配網程式碼

import network
import socket,json
from machine import Pin, Timer
import time
led_pin = Pin(4, Pin.OUT)
# 配置熱點模式
AP_SSID = 'myqiu_Setup'
AP_PASSWORD = 'setup123'
# Captive portal的HTML頁面
HTML = """
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
    <title>ESP32 WiFi Setup</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            font-family: Arial, sans-serif;
        }
        form {
            display: flex;
            flex-direction: column;
            align-items: center;
            background-color: #f0f0f0;
            padding: 20px;
            border-radius: 5px;
        }
        label, input {
            margin-bottom: 10px;
        }
    </style>
</head>
<body>
    <form action="/connect" method="post">
        <label for="ssid">SSID:</label>
        <input type="text" id="ssid" name="ssid">
        <label for="password">Password:</label>
        <input type="password" id="password" name="password">
        <input type="submit" value="Connect">
    </form>
</body>
</html>

"""
wifi_conn = False
wifi_config = None
def start_ap():
    ap = network.WLAN(network.AP_IF)
    ap.active(True)
    ap.config(essid=AP_SSID, password=AP_PASSWORD)
#     print("AP模式已啟用: SSID '{}' 密碼 '{}'".format(AP_SSID, AP_PASSWORD))
    return ap
# 從 JSON 檔案中讀取 WiFi 資訊
def read_wifi_config():
    try:
        with open("wifi_config.json", 'r') as file:
            data = json.load(file)
            if data['ssid'] == "" and  data['password'] == "":
                return False
            return data['ssid'], data['password']
    except Exception as e:
        return None
def connect_wifi(ssid, password):
    global wifi_conn,wifi_config
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    try:
        if not wlan.isconnected():
            wlan.connect(ssid, password)
            while not wlan.isconnected():
                pass
#         print('Network config:', wlan.ifconfig())
        wifi_conn = True
        wifi_config=wlan.ifconfig()
        server_socket.close()
        return True
    except Exception as e:
        return "wifi not find"
def handle_connection(client, addr, ap):
    global wifi_config
#     print('客戶端連線來自', addr)
    request = client.recv(1024).decode()
#     print('請求內容:', request)

    if 'POST /connect' in request:
        # 從請求中提取SSID和密碼
        ssid_start = request.find('ssid=') + 5
        ssid_end = request.find('&', ssid_start)
        password_start = request.find('password=') + 9
        ssid = request[ssid_start:ssid_end]
        password = request[password_start:]
#         print('嘗試連線WiFi SSID:', ssid)
        wifi_data = {
            'ssid': ssid,
            'password': password
        }

        # 重置並連線到新WiFi網路
        if connect_wifi(ssid, password):
            response = "HTTP/1.1 200 OK\n\n<meta http-equiv='Content-Type' content='text/html; charset=utf-8'</>h1>已連線到WiFi。正在關閉AP模式...</h1>"
            client.send(response)
            client.close()
            # 關閉AP模式
#             print('關閉AP模式...')
            ap.active(False)
            with open("wifi_config.json", 'w') as file:
                json.dump(wifi_data, file)
            return True  # 表示連線成功
        else:
            response = "HTTP/1.1 200 OK\n\n<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/><h1>連線失敗。請重試。</h1>"
            client.send(response)
    else:
        response = 'HTTP/1.1 200 OK\nContent-Type: text/html\n\n' + HTML

    client.send(response)
    client.close()
    return False  # 表示連線失敗
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connected = False
def conn_wifi():
    global connected 
    ap = start_ap()
    server_socket.bind(('0.0.0.0', 80))
    server_socket.listen(1)
    print('Web伺服器已啟動,等待客戶端連線...')
    try:
        # 主程式部分
        while not connected:
            client_socket, addr = server_socket.accept()
            connected = handle_connection(client_socket, addr, ap)
    except KeyboardInterrupt:
        print("Exiting program...")
    finally:
        # 確保關閉伺服器套接字
        server_socket.close()
        led_pin.value(0)
def main():
    global wifi_conn,wifi_config
    while True:
        if read_wifi_config() ==False:
            conn_wifi()
        else:
            ssid,password = read_wifi_config()
            if wifi_conn != True:
                connect_wifi(ssid,password)
        if wifi_conn == True:
            return True
# if __name__ == "__main__":
#     print(main())

重新命名為AP.py 在你專案需要聯網前引入程式碼即可

相關文章