Веб-сервер на Raspberry Pi Pico: отдаём файлы из файловой системы (MicroPython)

Перевод статьи Raspberry Pi Pico Web Server: Files from Filesystem (MicroPython) — Random Nerd Tutorials.
Научимся делать на Raspberry Pi Pico веб-сервер, который отдаёт файлы, сохранённые в его файловой системе. Вместо того чтобы писать HTML прямо в скрипте MicroPython, часто удобнее держать HTML и прочие нужные файлы отдельно — в файловой системе Raspberry Pi Pico.

Это руководство подходит только для Raspberry Pi Pico W и Raspberry Pi Pico 2 W — у них есть Wi-Fi.
Содержание:
- Raspberry Pi Pico: отдаём файл из файловой системы (HTML-файл)
- Веб-сервер на Raspberry Pi Pico (файлы из файловой системы): HTML, CSS и JavaScript
Мы переделаем пример из предыдущего руководства так, чтобы HTML отдавался из файловой системы, а не был записан прямо в скрипте. Заодно добавим файлы CSS и JavaScript — так вы научитесь отдавать несколько файлов.
Если вы впервые делаете веб-сервер на Raspberry Pi Pico с MicroPython, советуем сначала пройти эти руководства, чтобы разобраться в процессе и основах:
- Raspberry Pi Pico: Web Server (MicroPython)
- Raspberry Pi Pico W: Asynchronous Web Server (MicroPython)
Что нужно заранее: прошивка MicroPython#
Для этого руководства на Raspberry Pi Pico должна быть установлена прошивка MicroPython. Ещё понадобится IDE, чтобы писать код и загружать его на плату.
Для Raspberry Pi Pico рекомендуем Thonny IDE. Как установить Thonny IDE, прошить MicroPython и загрузить код на плату — в этом руководстве:
Если вы только начинаете знакомство с Raspberry Pi Pico, пройдите одно из вводных руководств:
- Getting Started with Raspberry Pi Pico 2 and Pico 2 W
- Getting Started with Raspberry Pi Pico (and Pico W)
Raspberry Pi Pico: отдаём файл из файловой системы (HTML-файл)#
Прежде чем перейти к основному проекту, сделаем простой веб-сервер «Hello, World!», чтобы показать, какие шаги нужны, чтобы Pico W отдавал файлы из файловой системы.
Это удобно, если вы хотите создавать и отдавать отдельные файлы HTML, CSS, JavaScript и прочие, а не писать всё в переменной внутри скрипта MicroPython.
Порядок действий такой.
1) Откройте новый файл в Thonny IDE и скопируйте в него следующий HTML.
<!DOCTYPE html>
<html>
<head>
<title>Pico Web Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1>Raspberry Pi Pico Web Server</h1>
<p>Hello, World!</p>
</body>
</html>

HTML-файл в Thonny IDE
2) Убедитесь, что Thonny IDE подключена к вашему RPi Pico. Затем загрузите файл в файловую систему Pico: File > Save as… и выберите Raspberry Pi Pico.

Сохраняем файл на Raspberry Pi Pico
3) Сохраните файл под именем index.html.

Имя файла — index.html
Теперь HTML-файл лежит в файловой системе Pico. Если открыть View > Files, вы увидите там файл index.html.

index.html в файловой системе Pico
4) Создайте в Thonny IDE ещё один файл — это будет скрипт MicroPython.
# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-web-server-filesystem-micropython/
# Import necessary modules
import network
import socket
import time
# Wi-Fi credentials
ssid = 'REPLACE_WITH_YOUR_SSID'
password = 'REPLACE_WITH_YOUR_PASSWORD'
# Variable to save the HTML file path
HTML_FILE_PATH = "index.html"
# Function to read and return HTML content from the file
def read_file(filepath):
with open(filepath, "r") as file:
return file.read()
# Init Wi-Fi Interface
def init_wifi(ssid, password):
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
# Connect to your network
wlan.connect(ssid, password)
# Wait for Wi-Fi connection
connection_timeout = 10
while connection_timeout > 0:
print(wlan.status())
if wlan.status() >= 3:
break
connection_timeout -= 1
print('Waiting for Wi-Fi connection...')
time.sleep(1)
# Check if connection is successful
if wlan.status() != 3:
print('Failed to connect to Wi-Fi')
return False
else:
print('Connection successful!')
network_info = wlan.ifconfig()
print('IP address:', network_info[0])
return True
if not init_wifi(ssid, password):
print("Exiting program.")
else:
try:
# Set up socket and start listening
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(addr)
s.listen()
print('Listening on', addr)
# Main loop to listen for connections
while True:
try:
conn, addr = s.accept()
print('Got a connection from', addr)
# Receive and parse the request
request = conn.recv(1024)
request_str = request.decode('utf-8')
print('Request content:')
# Generate HTML response
response = read_file(HTML_FILE_PATH)
# Send the HTTP response and close the connection
conn.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
conn.send(response)
conn.close()
except OSError as e:
conn.close()
print('Connection closed')
except KeyboardInterrupt:
print('Server stopped by user.')
В скрипте нужно:
- указать путь к HTML-файлу в файловой системе. У нас он лежит в корневом каталоге, поэтому путь — просто
index.html:
# Variable to save the HTML file path
HTML_FILE_PATH = "index.html"
- прочитать файл из файловой системы и вернуть его содержимое. Для этого можно написать такую функцию:
# Function to read and return HTML content from the file
def read_file(filepath):
with open(filepath, "r") as file:
return file.read()
Подробнее о работе с файлами на Raspberry Pi Pico — в руководстве Raspberry Pi Pico: Handling Files and Directories (MicroPython).
Это простой веб-сервер, который лишь возвращает HTML-страницу при обращении к IP-адресу платы. Поэтому обрабатывать нужно только запрос к корневому URL (/). Главный цикл слушает HTTP-запросы:
# Main loop to listen for connections
while True:
try:
conn, addr = s.accept()
print('Got a connection from', addr)
# Receive and parse the request
request = conn.recv(1024)
request_str = request.decode('utf-8')
print('Request content:')
Получив запрос, готовим ответ. Его содержимое — HTML-текст из файла index.html. Чтобы сформировать ответ, достаточно прочитать HTML-файл созданной ранее функцией read_file(), передав ей HTML_FILE_PATH:
# Generate HTML response
response = read_file(HTML_FILE_PATH)
Остаётся отправить ответ. Сначала — HTTP-заголовок с типом содержимого: мы отправляем HTML (Content-type: text/html).
conn.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
Затем — сам HTML-текст, сохранённый в переменной response:
conn.send(response)
И наконец закрываем соединение:
conn.close()
Вот и все шаги, нужные для того, чтобы отдавать файлы из файловой системы Pico.
Проверяем веб-сервер#
Не забудьте вписать данные своей сети в эти строки:
# Wi-Fi credentials
ssid = 'REPLACE_WITH_YOUR_SSID'
password = 'REPLACE_WITH_YOUR_PASSWORD'
Чтобы проверить веб-сервер, загрузите скрипт MicroPython на Raspberry Pi Pico и сохраните его под именем main.py.

Сохраняем скрипт как main.py
Или нажмите зелёную кнопку запуска, чтобы выполнить код на плате без загрузки.

Кнопка запуска в Thonny IDE
Когда связь между Pico и Thonny IDE установлена, IP-адрес Pico появится в консоли (Shell).

IP-адрес платы в консоли
Откройте браузер и введите этот IP-адрес. Должна открыться HTML-страница, которую вы сохранили в файловой системе.

Страница из файловой системы Pico в браузере
Если нужно отдавать больше файлов — например, CSS или JavaScript, — придётся разбирать HTTP-запрос и формировать ответ соответственно: брать запрошенный файл из файловой системы и ставить в заголовке подходящий Content-type. Как это сделать, покажем дальше.
Веб-сервер на Raspberry Pi Pico (файлы из файловой системы)#
Прежде чем начать, кратко посмотрим, что умеет веб-сервер, который мы сделаем:

Готовый проект
Что делает наш пример:
- это асинхронный веб-сервер;
- он отдаёт HTML-страницу, на которой есть:
- две кнопки для включения и выключения светодиода (встроенного светодиода Pico);
- блок с показаниями встроенного датчика температуры Pico (читаем его через пакет picozero);
- кнопка для запроса нового значения температуры;
- HTML-страница хранится в файловой системе Pico;
- также отдаётся CSS-файл со стилями страницы (тоже в файловой системе);
- и JavaScript-файл (тоже в файловой системе), который обрабатывает нажатия кнопок.

Как это работает
Этот веб-сервер основан на более простом, который мы делали в предыдущем руководстве. Если хотите начать с чего-то попроще, загляните сначала туда: Raspberry Pi Pico W: Asynchronous Web Server (MicroPython).
Создаём HTML-файл#
Откройте новый файл в Thonny IDE и скопируйте в него следующий HTML.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Pico Web Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="style.css">
<script src="script.js" defer></script>
</head>
<body>
<h1>Raspberry Pi Pico Web Server</h1>
<p>LED State: <strong id="led-status" class="status">{state}</strong></p>
<p>
<button onclick="turnOn()" class="button">ON</button>
<button onclick="turnOff()" class="button button2">OFF</button>
</p>
<p>
<span class="sensor-labels">Temperature:</span>
<span id="temp_c" class="temp-value">{temperature_c}</span><span class="units">°C</span>
/
<span id="temp_f" class="temp-value">{temperature_f}</span><span class="units">°F</span>
</p>
<p>
<button onclick="getNewReading()" class="button-refresh" style="width: 220px;">
Get New Reading
</button>
</p>
</body>
</html>
Сохраните этот файл в файловую систему Raspberry Pi Pico: File > Save as…, выберите Raspberry Pi Pico и назовите файл index.html.
Как это работает#
Кратко разберём части HTML-файла, важные для этого примера. Можно и сразу перейти к следующему разделу.
Подключение файлов CSS и JavaScript
Указываем, что подключаем CSS- и JavaScript-файлы. При загрузке HTML-страницы браузер запросит эти файлы: style.css и script.js.
<link rel="stylesheet" type="text/css" href="style.css">
<script src="script.js" defer></script>
Отображение состояния светодиода
Здесь есть блок, показывающий текущее состояние светодиода. В нём — заполнитель {state}, на место которого код MicroPython подставит текущее состояние с помощью форматирования строк. У элемента с состоянием есть id led-status (id="led-status"), чтобы обращаться к нему из JavaScript.
<p>LED State: <strong id="led-status" class="status">{state}</strong></p>

Кнопки ON и OFF
Дальше идёт абзац с двумя кнопками для управления светодиодом. При нажатии ON или OFF вызываются JavaScript-функции turnOn() и turnOff(). Как они работают, увидим в следующем разделе.
<p>
<button onclick="turnOn()" class="button">ON</button>
<button onclick="turnOff()" class="button button2">OFF</button>
</p>

Отображение температуры
Есть блок для вывода температуры. Здесь тоже есть id, чтобы обращаться к этим элементам из JavaScript (id="temp_c" и id="temp_f"), и заполнители {temperature_c} и {temperature_f}.
<p>
<span class="sensor-labels">Temperature:</span>
<span id="temp_c" class="temp-value">{temperature_c}</span><span class="units">°C</span>
/
<span id="temp_f" class="temp-value">{temperature_f}</span><span class="units">°F</span>
</p>

Запрос нового значения температуры
И наконец — кнопка для запроса нового значения температуры. При нажатии вызывается JavaScript-функция getNewReading().
<p>
<button onclick="getNewReading()" class="button-refresh" style="width: 220px;">
Get New Reading
</button>
</p>

Создаём JavaScript-файл#
Откройте новый файл в Thonny IDE и скопируйте следующий код на JavaScript. Загрузите его на Raspberry Pi Pico под именем script.js.
// Turn LED ON
async function turnOn() {
try {
const response = await fetch('/lighton');
const data = await response.json();
document.getElementById('led-status').textContent = data.state;
} catch (error) {
console.error('Error turning LED ON:', error);
alert('Failed to turn LED ON');
}
}
// Turn LED OFF
async function turnOff() {
try {
const response = await fetch('/lightoff');
const data = await response.json();
document.getElementById('led-status').textContent = data.state;
} catch (error) {
console.error('Error turning LED OFF:', error);
alert('Failed to turn LED OFF');
}
}
// Get new temperature reading
async function getNewReading() {
try {
const response = await fetch('/temperature');
const data = await response.json();
document.getElementById('temp_c').textContent = data.temperature_c;
document.getElementById('temp_f').textContent = data.temperature_f;
} catch (error) {
console.error('Error fetching temperature:', error);
alert('Failed to get new reading');
}
}
Как это работает#
Кратко разберём этот код JavaScript. Можно и сразу перейти к следующему разделу.
Включение и выключение светодиода
Функция turnOn() делает запрос по пути /lighton. Ответом будет JSON такого вида (его формирует файл MicroPython):
{
"state": state
}
Получив ответ, функция берёт его содержимое, data.state, и обновляет состояние светодиода на странице.
async function turnOn() {
try {
const response = await fetch('/lighton');
const data = await response.json();
updateLedStatus(data.state);
} catch (error) {
console.error('Error turning LED ON:', error);
alert('Failed to turn LED ON');
}
}
Функция turnOff() работает так же, только для кнопки OFF.
// Turn LED OFF
async function turnOff() {
try {
const response = await fetch('/lightoff');
const data = await response.json();
updateLedStatus(data.state);
} catch (error) {
console.error('Error turning LED OFF:', error);
alert('Failed to turn LED OFF');
}
}
Примечание переводчика: в полном листинге выше вместо updateLedStatus() состояние обновляется напрямую через document.getElementById('led-status').textContent — используйте именно полный листинг.
Получение нового значения температуры
Кнопка Get New Reading вызывает JavaScript-функцию getNewReading(), которая делает запрос по URL /temperature. Запрос получает сервер (RPi Pico), а что делать с ним, мы описываем в файле MicroPython. В ответ сервер шлёт JSON такого вида:
{
"temperature_c": temperature_c,
"temperature_f": temperature_f
}
Функция getNewReading() получает данные и подставляет их в соответствующие HTML-элементы.
async function getNewReading() {
try {
const response = await fetch('/temperature');
const data = await response.json();
document.getElementById('temp_c').textContent = data.temperature_c;
document.getElementById('temp_f').textContent = data.temperature_f;
} catch (error) {
console.error('Error fetching temperature:', error);
alert('Failed to get new reading');
}
}
Создаём CSS-файл#
Откройте новый файл в Thonny IDE и скопируйте следующий CSS. Сохраните его на Raspberry Pi Pico под именем style.css.
html {
font-family: Arial;
background-color: #FFFFF7;
color: #333;
margin: 0;
padding: 0;
}
body {
max-width: 920px;
width: 100%;
margin: 0 auto;
text-align: center;
padding: 15px;
box-sizing: border-box;
}
h1 {
color: #0F3376;
padding: 25px 0 15px 0;
font-size: 2.1rem;
margin: 0;
}
p {
font-size: 1.55rem;
margin: 20px auto;
}
.button {
display: inline-block;
background-color: #00A676;
border: none;
border-radius: 6px;
color: white;
padding: 14px 32px;
text-decoration: none;
font-size: 1.25rem;
margin: 8px 12px;
cursor: pointer;
transition: background-color 0.3s ease, transform 0.1s ease;
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.2);
width: 170px;
}
.button:hover {
background-color: #008c63;
transform: translateY(-2px);
}
.button2 {
background-color: #f44336;
}
.button2:hover {
background-color: #d32f2f;
}
.button-refresh {
background-color: #f0f0f0;
color: #444;
border: 1px solid #bbb;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
font-size: 1.15rem;
width: 230px;
padding: 12px 24px;
}
.button-refresh:hover {
background-color: #e0e0e0;
border-color: #999;
transform: translateY(-1px);
}
.sensor-labels {
font-size: 1.55rem;
font-weight: bold;
color: #444;
margin-right: 12px;
}
.temp-value {
font-size: 1.9rem;
font-weight: lighter;
color: #0F3376;
}
.units {
font-size: 1.45rem;
color: #555;
margin-left: 3px;
}
.status {
font-weight: bold;
color: #0F3376;
}
a {
text-decoration: none;
}
Скрипт MicroPython: веб-сервер, отдающий файлы из файловой системы#
Теперь, когда все нужные файлы лежат в файловой системе Raspberry Pi Pico, напишем веб-сервер, который будет их отдавать, управлять GPIO и присылать температуру по запросу.
# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-web-server-filesystem-micropython/
# Import necessary modules
import network
import socket
import time
from picozero import pico_temp_sensor #must install the picozero package
from machine import Pin
import json
ssid = 'REPLACE_WITH_YOUR_SSID'
password = 'REPLACE_WITH_YOUR_PASSWORD'
# Constant variables to save the files path
HTML_FILE_PATH = "index.html"
CSS_FILE_PATH = "style.css"
JS_FILE_PATH ="script.js"
# Create an LED object on pin 'LED' (this is the onboard LED)
led = Pin('LED', Pin.OUT)
# Initialize LED state
state = 'OFF'
# Function to read content from the file
def read_file(filepath):
with open(filepath, "r") as file:
return file.read()
# Get sensor readings
# Pico internal temperature sensor
def get_temperature():
temperature_c = pico_temp_sensor.temp
temperature_f = temperature_c * (9/5) + 32
temperature_c = round(temperature_c)
temperature_f = round(temperature_f)
return temperature_c, temperature_f
# HTML template for the webpage
def webpage(state):
html_content = read_file(HTML_FILE_PATH)
temperature_c, temperature_f = get_temperature()
html = html_content.format(state=state, temperature_c=temperature_c, temperature_f=temperature_f)
return html
# Init Wi-Fi Interface
def init_wifi(ssid, password):
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
# Connect to your network
wlan.connect(ssid, password)
# Wait for Wi-Fi connection
connection_timeout = 10
while connection_timeout > 0:
print(wlan.status())
if wlan.status() >= 3:
break
connection_timeout -= 1
print('Waiting for Wi-Fi connection...')
time.sleep(1)
# Check if connection is successful
if wlan.status() != 3:
print('Failed to connect to Wi-Fi')
return False
else:
print('Connection successful!')
network_info = wlan.ifconfig()
print('IP address:', network_info[0])
return True
if not init_wifi(ssid, password):
print("Exiting program.")
else:
try:
# Set up socket and start listening
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(addr)
s.listen()
print('Listening on', addr)
# Main loop to listen for connections
while True:
try:
conn, addr = s.accept()
print('Got a connection from', addr)
# Receive and parse the request
request = conn.recv(1024)
request_str = request.decode('utf-8')
print('Request content:')
try:
path = request.split()[1]
print('Requested path:', path)
except IndexError:
pass
# Process the request and update variables19
if path == b'/lighton':
print('LED on')
led.value(1)
state = 'ON'
response = json.dumps({"state": state})
content_type = 'application/json'
elif path == b'/lightoff':
print('LED off')
led.value(0)
state = 'OFF'
response = json.dumps({"state": state})
content_type = 'application/json'
elif path == b'/temperature':
print('New temperature value requested')
temperature_c, temperature_f = get_temperature()
data = {
"temperature_c": temperature_c,
"temperature_f": temperature_f
}
response = json.dumps(data)
content_type = 'application/json'
# process the request and send the files
elif path == b'/style.css':
response = read_file(CSS_FILE_PATH)
content_type = 'text/css'
elif path == b'/script.js':
response = read_file(JS_FILE_PATH)
content_type = 'text/javascript'
else: # / root path
response = webpage(state)
content_type = 'text/html'
# Send the HTTP response and close the connection
conn.send(f'HTTP/1.0 200 OK\r\nContent-type: {content_type}\r\n\r\n')
conn.send(response)
conn.close()
except OSError as e:
conn.close()
print('Connection closed')
except KeyboardInterrupt:
print('Server stopped by user.')
Установка пакета picozero
В этом примере на веб-страницу выводятся показания встроенного датчика температуры Pico. Чтобы их получить, используем пакет picozero. В Thonny IDE откройте Tools > Manage packages…, найдите picozero и установите пакет picozero @PyPI.
Как это работает#
Кратко разберём, как работает код. Можно и сразу перейти к разделу с проверкой.
Пути к файлам
В этом примере нужно отдавать три разных файла: index.html, style.css и script.js. Начинаем с того, что задаём пути к ним. Файлы лежат в корневом каталоге файловой системы, так что достаточно указать их имена.
# Constant variables to save the files path
HTML_FILE_PATH = "index.html"
CSS_FILE_PATH = "style.css"
JS_FILE_PATH ="script.js"
Чтение файла из файловой системы
Как и в предыдущем простом примере, нужна функция, которая читает и возвращает содержимое файлов из файловой системы, — read_file().
# Function to read content from the file
def read_file(filepath):
with open(filepath, "r") as file:
return file.read()
HTML-шаблон
Функция webpage() возвращает веб-страницу с текущим состоянием GPIO и последними показаниями температуры. Эти значения подставляются в нужные места содержимого HTML-файла методом format(). Обратите внимание на заполнители в HTML-файле: {state}, {temperature_c} и {temperature_f}.
# HTML template for the webpage
def webpage(state):
html_content = read_file(HTML_FILE_PATH)
temperature_c, temperature_f = get_temperature()
html = html_content.format(state=state, temperature_c=temperature_c, temperature_f=temperature_f)
return html
По этому шаблону мы отдаём страницу при первом обращении к корневому URL Raspberry Pi Pico. А при нажатии кнопок JavaScript обновляет только значения, не перезагружая всю страницу.
Обработка запросов
Дальше в главном цикле (while True:) проверяем содержимое запроса, формируем и отправляем соответствующий ответ.
# Main loop to listen for connections
while True:
try:
conn, addr = s.accept()
print('Got a connection from', addr)
# Receive and parse the request
request = conn.recv(1024)
request_str = request.decode('utf-8')
print('Request content:')
try:
path = request.split()[1]
print('Requested path:', path)
except IndexError:
pass
Открывая страницу, браузер запросит файлы style.css и script.js — то есть сделает запросы по путям /style.css и /script.js. Чтобы сформировать ответ, читаем содержимое CSS- или JavaScript-файла из файловой системы функцией read_file(). Также нужно указать соответствующий тип содержимого.
# process the request and send the files
elif path == b'/style.css':
response = read_file(CSS_FILE_PATH)
content_type = 'text/css'
elif path == b'/script.js':
response = read_file(JS_FILE_PATH)
content_type = 'text/javascript'
В конце отправляем заголовок ответа с типом содержимого и сам ответ.
# Send the HTTP response and close the connection
conn.send(f'HTTP/1.0 200 OK\r\nContent-type: {content_type}\r\n\r\n')
conn.send(response)
Кроме того, когда пользователь нажимает кнопки на странице, мы отправляем клиенту JSON:
- кнопка ON → запрос /lighton;
- кнопка OFF → запрос /lightoff;
- кнопка Get New Reading → запрос /temperature.
В этом случае тип содержимого ответа — application/json.
# Process the request and update variables19
if path == b'/lighton':
print('LED on')
led.value(1)
state = 'ON'
response = json.dumps({"state": state})
content_type = 'application/json'
elif path == b'/lightoff':
print('LED off')
led.value(0)
state = 'OFF'
response = json.dumps({"state": state})
content_type = 'application/json'
elif path == b'/temperature':
print('New temperature value requested')
temperature_c, temperature_f = get_temperature()
data = {
"temperature_c": temperature_c,
"temperature_f": temperature_f
}
response = json.dumps(data)
content_type = 'application/json'
Наконец, если запрос не совпал ни с одним из перечисленных, значит, клиент обратился к корневому URL / или к какому-то другому, здесь не обрабатываемому. В этом случае просто отдаём HTML-страницу с текущими значениями температуры и состояния светодиода: формируем ответ вызовом webpage(), передав ей текущее состояние светодиода.
else: # / root path
response = webpage(state)
content_type = 'text/html'
Проверяем веб-сервер#
Убедитесь, что в файловую систему Pico загружены файлы:
index.htmlscript.jsstyle.css
Убедитесь также, что вы установили пакет picozero.
Затем загрузите скрипт MicroPython в файловую систему RPi под именем main.py или просто запустите его зелёной кнопкой Run.
Если открыть View > Files, картина должна быть примерно такой.

Файлы в файловой системе Raspberry Pi Pico
Сервер запустится, а IP-адрес Pico появится в консоли. Откройте этот адрес в браузере.
Pico отдаст index.html, style.css и script.js, и вы увидите такую страницу.

Готовая веб-страница
Кнопками ON и OFF можно управлять светодиодом, а кнопкой Get New Reading — запрашивать новое значение температуры.
Итоги#
В этом руководстве мы сделали на Raspberry Pi Pico веб-сервер, который отдаёт файлы из своей файловой системы. Сначала разобрали, как отдать простую HTML-страницу:
- сохраняем HTML-файл в файловой системе Pico;
- пишем функцию, которая читает этот файл и сохраняет его содержимое в переменной MicroPython;
- формируем HTTP-ответ с этим содержимым.
Затем разобрались, как отдавать остальные нужные странице файлы — CSS и JavaScript, — и как отправлять JSON, который обрабатывает JavaScript.
Если файлов несколько, это более практичный способ делать веб-серверы на Pico: файлы лежат упорядоченно, и вносить изменения потом проще.
Другие руководства по RPi Pico, которые могут вам понравиться: