這個Python程式碼的主要功能是利用ESP32-CAM模組建立一個Wi-Fi連接的網頁伺服器,用於實時攝影和圖像捕捉。以下是程式碼的主要組件及其功能說明與完整註解:
連接Wi-Fi:設置並連接到指定的無線網絡。
相機初始化:設置相機模組,選擇圖像大小和質量。
建立Web伺服器:在本地網絡中建立一個伺服器,讓其他裝置可以訪問和控制ESP32-CAM。
處理HTTP請求:接收和處理來自客戶端的HTTP請求,根據請求的URL,返回HTML頁面或捕捉的圖片。
python
複製程式碼
#20241022
import machine
import network
import socket
import select
import camera
import time
import gc
# Wi-Fi設定
SSID = 'Bili-Net' # Wi-Fi名稱
PASSWORD = '0932388283' # Wi-Fi密碼
# 初始化相機設定
def init_camera():
retry = 10 # 最多重試10次
while retry > 0:
try:
camera.init(0, format=camera.JPEG) # 初始化相機,設定格式為JPEG
camera.framesize(camera.FRAME_QVGA) # 設定影像解析度為QVGA
camera.quality(10) # 設定影像質量
print("相機初始化成功!")
return
except Exception as e:
print("相機初始化失敗,重試中...", e)
retry -= 1
time.sleep(1)
raise Exception("相機初始化最終失敗")
# 連接Wi-Fi
def connect_to_wifi():
station = network.WLAN(network.STA_IF) # 建立無線網絡接口
station.active(True) # 啟動接口
station.connect(SSID, PASSWORD) # 連接到Wi-Fi
for i in range(10): # 嘗試10次連接
if station.isconnected(): # 檢查是否連接成功
break
time.sleep(1)
else:
print("Failed to connect to Wi-Fi.")
return None
print('Connected to Wi-Fi.')
print('Network config:', station.ifconfig())
return station
# 定義Web伺服器
def web_server(station):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 建立socket
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 設定socket選項
s.setblocking(0) # 設置非阻塞模式
s.bind(('', 80)) # 綁定端口80
s.listen(5) # 監聽連接
print('Web server running on http://{}'.format(station.ifconfig()[0]))
socket_list = [s]
try:
while True:
gc.collect() # 垃圾回收
readable, _, _ = select.select(socket_list, [], [], 5) # 檢查可讀socket
for sock in readable:
if sock is s:
conn, addr = s.accept() # 接受連接
conn.setblocking(0) # 設置非阻塞模式
socket_list.append(conn) # 加入連接列表
print('Got a connection from %s' % str(addr))
else:
handle_connection(sock, socket_list)
finally:
s.close()
# 處理客戶端連接
def handle_connection(conn, socket_list):
conn.settimeout(10) # 設置超時
try:
request = conn.recv(1024).decode('utf-8') # 接收數據
if '/capture' in request: # 檢查是否為圖像捕捉請求
send_image(conn)
else:
send_html(conn) # 發送HTML頁面
except OSError as e:
print('Connection closed: OSError', e)
finally:
conn.close()
if conn in socket_list:
socket_list.remove(conn)
# 發送圖像數據
def send_image(conn):
photo = camera.capture() # 捕捉圖像
if photo:
conn.sendall(b'HTTP/1.1 200 OK\r\n')
conn.sendall(b'Content-Type: image/jpeg\r\n')
conn.sendall(b'Connection: close\r\n\r\n')
for i in range(0, len(photo), 1024):
conn.sendall(photo[i:i+1024])
else:
conn.sendall(b'HTTP/1.1 404 Not Found\r\n')
conn.sendall(b'Connection: close\r\n\r\n')
print("Failed to capture image")
# 發送HTML頁面
def send_html(conn):
html = """ # HTML模板,顯示攝影頁面
<!DOCTYPE html>
<html>
...
</html>
"""
conn.sendall(b'HTTP/1.1 200 OK\r\n')
conn.sendall(b'Content-Type: text/html; charset=utf-8\r\n')
conn.sendall(b'Connection: close\r\n\r\n')
conn.sendall(html.encode('utf-8'))
# 主程序
def main():
station = connect_to_wifi()
if station:
init_camera()
web_server(station)
if __name__ == '__main__':
main()
在初始化相機過程中,可以考慮加入更多的錯誤處理和異常回報,以便於調試和維護。
在Web服務器的實現中,應該更詳細地處理不同的HTTP請求類型和錯誤情況,以增強伺服器的穩定性和用戶體驗。
可以考慮引入日誌記錄功能,記錄重要的系統事件和錯誤信息,有助於未來的問題追踪和系統優化。