{"id":144635,"date":"2024-01-11T13:55:58","date_gmt":"2024-01-11T13:55:58","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=144635"},"modified":"2024-05-06T10:53:07","modified_gmt":"2024-05-06T10:53:07","slug":"raspberry-pi-pico-web-server-micropython","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-web-server-micropython\/","title":{"rendered":"Raspberry Pi Pico: Web Server (MicroPython)"},"content":{"rendered":"\n<p>In this guide, you&#8217;ll learn how to create a basic Raspberry Pi Pico local web server to control outputs and fetch data. As an example, we&#8217;ll create a web page to control an LED on and off and fetch some random values generated by the Pico. This example can be easily modified or extended to control multiple outputs and fetch data from sensors instead of random numbers.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" width=\"1200\" height=\"675\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-Web-Server-Micropython.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Raspberry Pi Pico Basic Web Server MicroPython\" class=\"wp-image-144648\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-Web-Server-Micropython.jpg?w=1280&amp;quality=100&amp;strip=all&amp;ssl=1 1280w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-Web-Server-Micropython.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-Web-Server-Micropython.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-Web-Server-Micropython.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n<p class=\"rntbox rntcred\">This tutorial is <strong>only compatible with the Raspberry Pi Pico W<\/strong> that comes with Wi-Fi support. Throughout this tutorial whenever we refer to the Raspberry Pi Pico, we&#8217;re referring to the Raspberry Pi Pico W.<\/p>\n\n\n\n<p class=\"rntbox rntclblue\"><strong>New to the Raspberry Pi Pico?<\/strong> Start here: <a href=\"https:\/\/randomnerdtutorials.com\/getting-started-raspberry-pi-pico-w\/\" title=\"\">Getting Started with Raspberry Pi Pico<\/a>.<\/p>\n\n\n\n<p><strong>Table of Contents<\/strong><\/p>\n\n\n\n<p>This tutorial covers the following topics:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"#web-server-basic-concepts\" title=\"\">Introducing Basic Web Server Concepts<\/a>\n<ul class=\"wp-block-list\">\n<li><a href=\"#pico-web-server\" title=\"\">The Raspberry Pi Pico as a Web Server<\/a><\/li>\n\n\n\n<li><a href=\"#client-server\" title=\"\">Client and Server<\/a><\/li>\n\n\n\n<li><a href=\"#ip-address\" title=\"\">IP Address<\/a><\/li>\n\n\n\n<li><a href=\"#sockets\" title=\"\">Sockets<\/a><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><a href=\"#project-overview\" title=\"\">Project Overview<\/a><\/li>\n\n\n\n<li><a href=\"#html-page\" title=\"\">Creating the HTML Page<\/a><\/li>\n\n\n\n<li><a href=\"#raspberry-pi-pico-web-server-micropython-code\" title=\"\">Raspberry Pi Pico Web Server &#8211; MicroPython Script<\/a>\n<ul class=\"wp-block-list\">\n<li><a href=\"#how-code-works\" title=\"\">How does the code work?<\/a><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><a href=\"#demonstration\" title=\"\">Raspberry Pi Pico Web Server Demonstration<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"prerequisites\">Prerequisites &#8211; MicroPython Firmware<\/h2>\n\n\n\n<p>To follow this tutorial you need MicroPython firmware installed in your Raspberry Pi Pico board. You also need an IDE to write and upload the code to your board. <\/p>\n\n\n\n<p>The recommended MicroPython IDE for the Raspberry Pi Pico is Thonny IDE. Follow the next tutorial to learn how to install Thonny IDE, flash MicroPython firmware, and upload code to the board.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/getting-started-raspberry-pi-pico-w\/#install-thonny-ide\" title=\"\">Programming Raspberry Pi Pico using MicroPython<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"web-server-basic-concepts\">Introducing Basic Concepts<\/h2>\n\n\n\n<p class=\"rntbox rntclgreen\">Already familiar with basic web server concepts? <a href=\"#project-overview\" title=\"\">Jump to the Project Overview section<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"pico-web-server\">The Raspberry Pi Pico as a Web Server<\/h3>\n\n\n\n<p>In simple terms, a web server is a \u201ccomputer\u201d that provides web pages. It stores the website\u2019s files, including all HTML documents and related assets like images, CSS style sheets, fonts, and\/or other files. It also brings those files to the user\u2019s web browser device when the user makes a request to the server.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"1135\" height=\"351\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-Web-Server-example.png?resize=1135%2C351&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Raspberry Pi Pico Web Server\" class=\"wp-image-144691\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-Web-Server-example.png?w=1135&amp;quality=100&amp;strip=all&amp;ssl=1 1135w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-Web-Server-example.png?resize=300%2C93&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-Web-Server-example.png?resize=1024%2C317&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-Web-Server-example.png?resize=768%2C238&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 1135px) 100vw, 1135px\" \/><\/figure><\/div>\n\n\n<p>When using the Raspberry Pi Pico as a web server, you&#8217;re essentially turning it into a small computer that stores and provides web pages. As users access a web page, their browsers send requests to the Pico using Hypertext Transfer Protocol (HTTP). The Pico then responds by sending back the requested web page.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"client-server\">Client and Server<\/h3>\n\n\n\n<p>When you type a URL in your browser,&nbsp;in the background, you (the client) send a request via Hypertext Transfer Protocol (HTTP) to a server. When the server receives the request, it sends a response through HTTP, and you will see the web page requested in your browser. Clients and servers communicate over a computer network.<\/p>\n\n\n\n<p>In simple terms, clients make requests to servers. Servers handle the clients\u2019 requests. In this particular tutorial, the Raspberry Pi Pico will be the server, and you (your browser) will be the client.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"ip-address\">Ip Address<\/h3>\n\n\n\n<p>An IP address is a numerical label assigned to each device connected to a computer network. It is a series of four values separated by periods with each value ranging from 0 to 255. Here\u2019s an example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>192.168.1.75<\/code><\/pre>\n\n\n\n<p>At home, your devices are connected to a private network through your router (local network). All devices connected to your router are part of your local network. Inside this network, each device has its own IP address.<\/p>\n\n\n\n<p>Devices that are connected to the same router can access each other via the IP address. Devices outside your local network can\u2019t access your local devices using their local IP address.<\/p>\n\n\n\n<p>When you connect your Raspberry Pi Pico to your router, it becomes part of your local network. So, it will be assigned a unique local IP address and you can access it from your computer on your local network.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"sockets\">Sockets<\/h3>\n\n\n\n<p>We\u2019ll create our web server using <em>sockets <\/em>and the <a href=\"https:\/\/docs.python.org\/3\/library\/socket.html\" target=\"_blank\" rel=\"noopener\" title=\"\">Python socket API<\/a>.<\/p>\n\n\n\n<p>Sockets and the socket API are used to send messages across a network. They provide a form of&nbsp;inter-process communication (IPC).&nbsp;<\/p>\n\n\n\n<p>Sockets can be used in client-server applications, where one side acts as the server and waits for connections from clients \u2013 that\u2019s what we\u2019ll do here (the Raspberry Pi Pico is a server waiting for connections from clients).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"project-overview\">Project Overview<\/h2>\n\n\n\n<p>Before going straight to the project, it is important to outline what our web server will do so that it is easier to understand how everything works.<\/p>\n\n\n\n<p>We&#8217;ll create a simple web page with two buttons to control the Raspberry Pi Pico onboard LED on and off. The web page also has another button to request a new random value (this can easily be modified to request sensor readings).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"716\" height=\"471\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-WebServer.png?resize=716%2C471&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Raspberry Pi Pico Basic Web Server basic example\" class=\"wp-image-144652\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-WebServer.png?w=716&amp;quality=100&amp;strip=all&amp;ssl=1 716w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-WebServer.png?resize=300%2C197&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 716px) 100vw, 716px\" \/><\/figure><\/div>\n\n\n<p>Here&#8217;s a quick explanation of how everything works.<\/p>\n\n\n\n<p>When you enter the Raspberry Pi Pico address on your web browser, you&#8217;re making a request to the Raspberry Pi Pico on the root (\/) URL. When it receives that request, it responds with the HTML to build the web page we&#8217;ve seen previously.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1167\" height=\"629\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-it-works-1.png?resize=1167%2C629&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Raspberry Pi Pico Basic Web Server how it works request response\" class=\"wp-image-144651\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-it-works-1.png?w=1167&amp;quality=100&amp;strip=all&amp;ssl=1 1167w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-it-works-1.png?resize=300%2C162&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-it-works-1.png?resize=1024%2C552&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-it-works-1.png?resize=768%2C414&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 1167px) 100vw, 1167px\" \/><\/figure><\/div>\n\n\n<p>When you click on the <em>Light on<\/em> button, it makes a request on the <strong>\/lighton?<\/strong> URL. When it receives that request, it turns the onboard LED on and sends the web page with the updated LED state.<\/p>\n\n\n\n<p>When you click on the <em>Light off<\/em> button, a request is made on the <strong>\/lightoff? <\/strong>URL. When that happens, it will turn off the LED and send the web page with the current LED state.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"641\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-it-works-2.png?resize=1200%2C641&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Raspberry Pi Pico Basic Web Server How it Works Diagram\" class=\"wp-image-144653\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-it-works-2.png?w=1280&amp;quality=100&amp;strip=all&amp;ssl=1 1280w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-it-works-2.png?resize=300%2C160&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-it-works-2.png?resize=1024%2C547&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-it-works-2.png?resize=768%2C410&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n<p>Finally, we also have a button to request a random value from the Raspberry Pi Pico. This can be easily modified to request sensor readings or any other useful piece of information. That button sends a request on the <strong>\/value?<\/strong> URL. When the Pico receives that request, it generates a new random value and sends the HTML page updated with that new value.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"493\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-it-works-3.png?resize=1200%2C493&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Basic Raspberry Pi Pico Web Server Request a new value\" class=\"wp-image-144654\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-it-works-3.png?w=1280&amp;quality=100&amp;strip=all&amp;ssl=1 1280w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-it-works-3.png?resize=300%2C123&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-it-works-3.png?resize=1024%2C421&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-it-works-3.png?resize=768%2C316&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"html-page\">The HTML Page<\/h2>\n\n\n\n<p>Below you can find the HTML we&#8217;ll use to build the web page:<\/p>\n\n\n\n<pre class=\"wp-block-code language-html\"><code>&lt;!DOCTYPE html&gt;\n&lt;html&gt;\n&lt;head&gt;\n    &lt;title&gt;Pico Web Server&lt;\/title&gt;\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;h1&gt;Raspberry Pi Pico Web Server&lt;\/h1&gt;\n    &lt;h2&gt;Led Control&lt;\/h2&gt;\n    &lt;form action=\".\/lighton\"&gt;\n        &lt;input type=\"submit\" value=\"Light on\" \/&gt;\n    &lt;\/form&gt;\n    &lt;br&gt;\n    &lt;form action=\".\/lightoff\"&gt;\n        &lt;input type=\"submit\" value=\"Light off\" \/&gt;\n    &lt;\/form&gt;\n    &lt;p&gt;LED state: <strong>{state}<\/strong>&lt;\/p&gt;\n    &lt;h2&gt;Fetch New Value&lt;\/h2&gt;\n    &lt;form action=\".\/value\"&gt;\n        &lt;input type=\"submit\" value=\"Fetch value\" \/&gt;\n    &lt;\/form&gt;\n    &lt;p&gt;Fetched value: <strong>{random_value}<\/strong>&lt;\/p&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n\n\n\n<p>In this particular example, we&#8217;ll save the contents of the HTML file in a variable in our MicroPython script (but, it can also be saved in a file in the Raspberry Pi Pico filesystem\u2014not covered in this tutorial).<\/p>\n\n\n\n<p>This HTML structure creates a basic web page for controlling an LED and fetching a random value, for interaction with a Raspberry Pi Pico web server.<\/p>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">{state}<\/span> and <span class=\"rnthl rntliteral\">{random_value}<\/span> variables are meant to be dynamically populated with values from the server-side logic.<\/p>\n\n\n\n<p>In summary, this HTML creates three different forms with buttons.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"raspberry-pi-pico-web-server-micropython-code\">Raspberry Pi Pico Web Server &#8211; MicroPython Script<\/h2>\n\n\n\n<p>Create a new file in Thonny IDE and copy the following code.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-python\"># Complete project details at https:\/\/RandomNerdTutorials.com\/raspberry-pi-pico-web-server-micropython\/\n\n# Import necessary modules\nimport network\nimport socket\nimport time\nimport random\nfrom machine import Pin\n\n# Create an LED object on pin 'LED'\nled = Pin('LED', Pin.OUT)\n\n# Wi-Fi credentials\nssid = 'REPLACE_WITH_YOUR_SSID'\npassword = 'REPLACE_WITH_YOUR_PASSWORD'\n\n# HTML template for the webpage\ndef webpage(random_value, state):\n    html = f&quot;&quot;&quot;\n        &lt;!DOCTYPE html&gt;\n        &lt;html&gt;\n        &lt;head&gt;\n            &lt;title&gt;Pico Web Server&lt;\/title&gt;\n            &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;\n        &lt;\/head&gt;\n        &lt;body&gt;\n            &lt;h1&gt;Raspberry Pi Pico Web Server&lt;\/h1&gt;\n            &lt;h2&gt;Led Control&lt;\/h2&gt;\n            &lt;form action=&quot;.\/lighton&quot;&gt;\n                &lt;input type=&quot;submit&quot; value=&quot;Light on&quot; \/&gt;\n            &lt;\/form&gt;\n            &lt;br&gt;\n            &lt;form action=&quot;.\/lightoff&quot;&gt;\n                &lt;input type=&quot;submit&quot; value=&quot;Light off&quot; \/&gt;\n            &lt;\/form&gt;\n            &lt;p&gt;LED state: {state}&lt;\/p&gt;\n            &lt;h2&gt;Fetch New Value&lt;\/h2&gt;\n            &lt;form action=&quot;.\/value&quot;&gt;\n                &lt;input type=&quot;submit&quot; value=&quot;Fetch value&quot; \/&gt;\n            &lt;\/form&gt;\n            &lt;p&gt;Fetched value: {random_value}&lt;\/p&gt;\n        &lt;\/body&gt;\n        &lt;\/html&gt;\n        &quot;&quot;&quot;\n    return str(html)\n\n# Connect to WLAN\nwlan = network.WLAN(network.STA_IF)\nwlan.active(True)\nwlan.connect(ssid, password)\n\n# Wait for Wi-Fi connection\nconnection_timeout = 10\nwhile connection_timeout &gt; 0:\n    if wlan.status() &gt;= 3:\n        break\n    connection_timeout -= 1\n    print('Waiting for Wi-Fi connection...')\n    time.sleep(1)\n\n# Check if connection is successful\nif wlan.status() != 3:\n    raise RuntimeError('Failed to establish a network connection')\nelse:\n    print('Connection successful!')\n    network_info = wlan.ifconfig()\n    print('IP address:', network_info[0])\n\n# Set up socket and start listening\naddr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]\ns = socket.socket()\ns.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\ns.bind(addr)\ns.listen()\n\nprint('Listening on', addr)\n\n# Initialize variables\nstate = &quot;OFF&quot;\nrandom_value = 0\n\n# Main loop to listen for connections\nwhile True:\n    try:\n        conn, addr = s.accept()\n        print('Got a connection from', addr)\n        \n        # Receive and parse the request\n        request = conn.recv(1024)\n        request = str(request)\n        print('Request content = %s' % request)\n\n        try:\n            request = request.split()[1]\n            print('Request:', request)\n        except IndexError:\n            pass\n        \n        # Process the request and update variables\n        if request == '\/lighton?':\n            print(&quot;LED on&quot;)\n            led.value(1)\n            state = &quot;ON&quot;\n        elif request == '\/lightoff?':\n            led.value(0)\n            state = 'OFF'\n        elif request == '\/value?':\n            random_value = random.randint(0, 20)\n\n        # Generate HTML response\n        response = webpage(random_value, state)  \n\n        # Send the HTTP response and close the connection\n        conn.send('HTTP\/1.0 200 OK\\r\\nContent-type: text\/html\\r\\n\\r\\n')\n        conn.send(response)\n        conn.close()\n\n    except OSError as e:\n        conn.close()\n        print('Connection closed')\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/Raspberry-Pi-Pico\/MicroPython\/main_Basic_Web_Server.py\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>You just need to insert your SSID and password on the following variables and the code should work straight away.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Wi-Fi credentials\nssid = 'REPLACE_WITH_YOUR_SSID'\npassword = 'REPLACE_WITH_YOUR_PASSWORD'<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"how-code-works\">How does the Code Work?<\/h3>\n\n\n\n<p>Continue reading to learn how the code works, or skip to the <a href=\"#demonstration\" title=\"\">Demonstration section<\/a>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Importing Libraries<\/h4>\n\n\n\n<p>Start by importing the required modules, including <span class=\"rnthl rntliteral\">network<\/span> for Wi-Fi, <span class=\"rnthl rntliteral\">socket<\/span> for communication between client and server, <span class=\"rnthl rntliteral\">time<\/span> for delays, <span class=\"rnthl rntliteral\">random<\/span> for generating random numbers, and <span class=\"rnthl rntliteral\">Pin<\/span> from <span class=\"rnthl rntliteral\">machine<\/span> for GPIO pin control.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>import network\nimport socket\nimport time\nimport random\nfrom machine import Pin<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Declaring the LED Pin<\/h4>\n\n\n\n<p>Create a <span class=\"rnthl rntliteral\">Pin<\/span> object named <span class=\"rnthl rntliteral\">led<\/span> that corresponds to the Raspberry Pi Pico onboard LED. It&#8217;s configured as an output pin. It will interpret <span class=\"rnthl rntliteral\">&#8216;LED&#8217;<\/span> as the onboard LED.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>led = Pin('LED', Pin.OUT)<\/code><\/pre>\n\n\n\n<p>Set the Wi-Fi credentials for the network you want to connect to. Modify these variables with your own credentials.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Wi-Fi credentials\nssid = 'REPLACE_WITH_YOUR_SSID'\npassword = 'REPLACE_WITH_YOUR_PASSWORD'<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Creating the Web Page<\/h4>\n\n\n\n<p>To generate the web page, we created a function called <span class=\"rnthl rntliteral\">webpage()<\/span> that accepts as arguments a random value and the LED state. We&#8217;re generating the web page in a function because it allows us to dynamically change its content at the time of sending it to the client. This way, we can send the page with the latest information about the GPIO state or random value.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># HTML template for the webpage\ndef webpage(random_value, state):\n    html = f\"\"\"\n        &lt;!DOCTYPE html&gt;\n        &lt;html&gt;\n        &lt;head&gt;\n            &lt;title&gt;Pico Web Server&lt;\/title&gt;\n            &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"&gt;\n        &lt;\/head&gt;\n        &lt;body&gt;\n            &lt;h1&gt;Raspberry Pi Pico Web Server&lt;\/h1&gt;\n            &lt;h2&gt;Led Control&lt;\/h2&gt;\n            &lt;form action=\".\/lighton\"&gt;\n                &lt;input type=\"submit\" value=\"Light on\" \/&gt;\n            &lt;\/form&gt;\n            &lt;br&gt;\n            &lt;form action=\".\/lightoff\"&gt;\n                &lt;input type=\"submit\" value=\"Light off\" \/&gt;\n            &lt;\/form&gt;\n            &lt;p&gt;LED state: {state}&lt;\/p&gt;\n            &lt;h2&gt;Fetch New Value&lt;\/h2&gt;\n            &lt;form action=\".\/value\"&gt;\n                &lt;input type=\"submit\" value=\"Fetch value\" \/&gt;\n            &lt;\/form&gt;\n            &lt;p&gt;Fetched value: {random_value}&lt;\/p&gt;\n        &lt;\/body&gt;\n        &lt;\/html&gt;\n        \"\"\"\n    return str(html)<\/code><\/pre>\n\n\n\n<p>To better understand how this works and the usage of f-strings along with curly braces <strong>{}<\/strong> to include variables in the HTML string, continue reading.<\/p>\n\n\n\n<p>The <strong>triple quotes (&#8220;&#8221;&#8221;)<\/strong> are used to create a multi-line string. This allows for easy formatting of the HTML content without needing to concatenate multiple strings. Our HTML content is more readable this way, but you can concatenate everything on the same line if you want to.<\/p>\n\n\n\n<p>The <strong>f<\/strong> before the opening triple quote denotes an f-string, which is a way to embed expressions inside string literals. In this case, it allows the inclusion of variables (<span class=\"rnthl rntliteral\">random_value<\/span> and <span class=\"rnthl rntliteral\">state<\/span>) directly within the string.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>html = f\"\"\"<\/code><\/pre>\n\n\n\n<p>The curly braces <strong>{}<\/strong> inside the f-string act as placeholders for variables. The variables inside the curly braces are replaced with their actual values during the string formatting.<\/p>\n\n\n\n<p>In summary, the <span class=\"rnthl rntliteral\">{state}<\/span> and <span class=\"rnthl rntliteral\">{random_value}<\/span> within the HTML content are placeholders for the actual values of the <span class=\"rnthl rntliteral\">state<\/span> and <span class=\"rnthl rntliteral\">random_value<\/span> variables.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>&lt;p&gt;LED state: {state}&lt;\/p&gt;<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>&lt;p&gt;Fetched value: {random_value}&lt;\/p&gt;<\/code><\/pre>\n\n\n\n<p>This dynamic string formatting makes it easy to incorporate variable values directly into the HTML content, providing a clean and readable way to generate dynamic web pages.<\/p>\n\n\n\n<p>When we call this function, it will return an HTML page with the current random value and LED state.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Connecting to the Internet<\/h4>\n\n\n\n<p>The following lines are responsible for connecting your Raspberry Pi Pico to your local network using the SSID and password you defined earlier.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Connect to WLAN\nwlan = network.WLAN(network.STA_IF)\nwlan.active(True)\nwlan.connect(ssid, password)<\/code><\/pre>\n\n\n\n<p>Wait for the Wi-Fi connection to be established. It checks the connection status, and if it&#8217;s <span class=\"rnthl rntliteral\">wlan.status() &gt;= 3<\/span> (this means it has even connected to the network or failed to connect), the loop exits. It waits for a maximum of 10 seconds.<\/p>\n\n\n\n<p>The method <span class=\"rnthl rntliteral\">wlan.status<\/span>, as the name suggests, checks the status of the Wi-Fi connection of the Raspberry Pi. This method returns an integer with the following meaning:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>0: WLAN is not enabled<\/li>\n\n\n\n<li>1: WLAN is currently scanning for networks<\/li>\n\n\n\n<li>2: WLAN is connecting to a network<\/li>\n\n\n\n<li>3: WLAN is connected to a network<\/li>\n\n\n\n<li>4: WLAN failed to connect to a network<\/li>\n<\/ul>\n\n\n\n<p>Then, we check if it&#8217;s connected or not (we know that status = 3 means it&#8217;s connected). If <span class=\"rnthl rntliteral\">wlan.status()<\/span> is different than 3, we know it failed to establish a connection.<\/p>\n\n\n\n<p>Otherwise, it means we succeed. In case we succeed, we can get the network information using the <span class=\"rnthl rntliteral\">ifconfig()<\/span> method. This method returns a tupple with the following information:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>network_info&#091;0]: The IP address assigned to the Pico on the network.\nnetwork_info&#091;1]: The subnet mask.\nnetwork_info&#091;2]: The gateway IP address.\nnetwork_info&#091;3]: The DNS (Domain Name System) server IP address.<\/code><\/pre>\n\n\n\n<p>We just need the IP address, so we just get the first element of the array (<span class=\"rnthl rntliteral\">network_info[0]<\/span>).<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>else:\n    print('Connection successful!')\n    network_info = wlan.ifconfig()\n    print('IP address:', network_info&#091;0])<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Creating a socket server<\/h4>\n\n\n\n<p>After establishing a connection with our network, we need to create a listening socket to listen for incoming requests and send the HTML text in response. For a better understanding, the following figure shows a diagram of how to create sockets for server-client interaction:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"688\" height=\"900\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/10\/socket-server.png?resize=688%2C900&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Creating a socket server diagram\" class=\"wp-image-76666\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/10\/socket-server.png?w=688&amp;quality=100&amp;strip=all&amp;ssl=1 688w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/10\/socket-server.png?resize=229%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 229w\" sizes=\"(max-width: 688px) 100vw, 688px\" \/><\/figure><\/div>\n\n\n<p>Set up a socket to listen on port 80. It uses the 0.0.0.0 address, indicating that it will listen on all available network interfaces. The <span class=\"rnthl rntliteral\">SO_REUSEADDR<\/span> option allows the socket to reuse the address (this way you won&#8217;t have problems with addresses already in use when you try to run the webserver after the first time).<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>addr = socket.getaddrinfo('0.0.0.0', 80)&#091;0]&#091;-1]\ns = socket.socket()\ns.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\ns.bind(addr)\ns.listen()<\/code><\/pre>\n\n\n\n<p>The following line gets information about the socket address, specifically the address and port.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>addr = socket.getaddrinfo('0.0.0.0', 80)&#091;0]&#091;-1]<\/code><\/pre>\n\n\n\n<p>Create a socket using <span class=\"rnthl rntliteral\">socket.socket()<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>s = socket.socket()<\/code><\/pre>\n\n\n\n<p>Next, bind the socket to an address (network interface and port number) using the <span class=\"rnthl rntliteral\">bind()<\/span> method. The <span class=\"rnthl rntliteral\">bind()<\/span> method accepts a tupple variable with the ip address, and port number, that we saved previously on the <span class=\"rnthl rntliteral\">addr<\/span> variable:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>s.bind(addr)<\/code><\/pre>\n\n\n\n<p>Put the socket into listening mode. This means it&#8217;s now ready to accept incoming connections.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>s.listen()<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Initializing Variables<\/h4>\n\n\n\n<p>Initialize variables for the LED state (<span class=\"rnthl rntliteral\">state<\/span>) and for the random value (<span class=\"rnthl rntliteral\">random_value<\/span>).<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Initialize variables\nstate = \"OFF\"\nrandom_value = 0<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Listening for Connections<\/h4>\n\n\n\n<p>In the while loop, we listen for requests and send responses. When a client connects, the server calls the <span class=\"rnthl rntliteral\">accept()<\/span> method to accept the connection. When a client connects, it saves a new socket object to accept and send data on the <span class=\"rnthl rntliteral\">conn<\/span> variable, and saves the client address to connect to the server on the <span class=\"rnthl rntliteral\">addr<\/span> variable.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>conn, addr = s.accept()<\/code><\/pre>\n\n\n\n<p>Then, print the address of the client saved on the <span class=\"rnthl rntliteral\">addr<\/span> variable.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>print('Got a connection from', addr)<\/code><\/pre>\n\n\n\n<p>The data is exchanged between the client and server using the <span class=\"rnthl rntliteral\">send()<\/span> and <span class=\"rnthl rntliteral\">recv()<\/span> methods.<\/p>\n\n\n\n<p>The following line gets the request received on the newly created socket and saves it in the <span class=\"rnthl rntliteral\">request<\/span> variable.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>request = conn.recv(1024)<\/code><\/pre>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">recv()<\/span> method receives the data from the client socket (remember that we\u2019ve created a new socket object on the <span class=\"rnthl rntliteral\">conn<\/span> variable). The argument of the <span class=\"rnthl rntliteral\">recv()<\/span> method specifies the maximum amount of data that can be received at once in bytes.<\/p>\n\n\n\n<p>The next line simply prints the content of the request:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>print('Request content = %s' % request)<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Get the Request Content<\/h4>\n\n\n\n<p>Then, we get the content of the request with <span class=\"rnthl rntliteral\">request.split()[1]<\/span>. It splits the received HTTP request string into a list of words and takes the second element (index 1) of the list. This is typically the path part of the HTTP request, which is the information that we need to know which button was clicked on the web interface.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>try:\n    request = request.split()&#091;1]\n    print('Request:', request)\nexcept IndexError:\n    pass<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Process the requests<\/h4>\n\n\n\n<p>We then check the contents of the request and act accordingly. If the request is on the <span class=\"rnthl rntliteral\">\/lighton?<\/span> path, we turn the LED on and update the <span class=\"rnthl rntliteral\">state<\/span> variable to <span class=\"rnthl rntliteral\">&#8216;ON&#8217;<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>if request == '\/lighton?':\n    print(\"LED on\")\n    led.value(1)\n    state = \"ON\"<\/code><\/pre>\n\n\n\n<p>If the request is <span class=\"rnthl rntliteral\">\/lightoff?<\/span>, we turn the LED off and update the state variable to <span class=\"rnthl rntliteral\">&#8216;OFF&#8217;<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>elif request == '\/lightoff?':\n    led.value(0)\n    state = 'OFF'<\/code><\/pre>\n\n\n\n<p>Finally, if the request is on the <span class=\"rnthl rntliteral\">\/value?<\/span> path, we generate a new random value and save it on the <span class=\"rnthl rntliteral\">random_value<\/span> variable.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>elif request == '\/value?':\n    random_value = random.randint(0, 20)<\/code><\/pre>\n\n\n\n<p>As we&#8217;ve mentioned previously, instead of generating a random value, you can <a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-ds18b20-micropython\/\" title=\"\">get sensor readings<\/a>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Sending the Response<\/h4>\n\n\n\n<p>After processing the request, we&#8217;ll call the <span class=\"rnthl rntliteral\">webpage()<\/span> function with <span class=\"rnthl rntliteral\">random_value<\/span> and <span class=\"rnthl rntliteral\">state<\/span> as arguments to generate an HTML page with the updated values. The content to generate the web page is saved on the <span class=\"rnthl rntliteral\">response<\/span> variable.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>response = webpage(random_value, state)  <\/code><\/pre>\n\n\n\n<p>Finally, send the response to the socket client using the <span class=\"rnthl rntliteral\">send()<\/span>&nbsp;method:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>conn.send('HTTP\/1.0 200 OK\\r\\nContent-type: text\/html\\r\\n\\r\\n')\nconn.send(response)<\/code><\/pre>\n\n\n\n<p>In the end, close the created socket.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>conn.close()<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading demonstration\" id=\"demonstration\">Raspberry Pi Pico Web Server &#8211; Demonstration<\/h2>\n\n\n\n<p>Run the previous code on your Raspberry Pi Pico. You just need to click on the Thonny IDE green <em>run<\/em> button.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"470\" height=\"114\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/thonny-ide-run-button.png?resize=470%2C114&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Thonny IDE Run Green Button\" class=\"wp-image-144594\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/thonny-ide-run-button.png?w=470&amp;quality=100&amp;strip=all&amp;ssl=1 470w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/thonny-ide-run-button.png?resize=300%2C73&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 470px) 100vw, 470px\" \/><\/figure><\/div>\n\n\n<p>The Raspberry Pi IP address will be printed after a few seconds. In my case, it&#8217;s 192.168.1.82.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"700\" height=\"231\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-Web-Server-Get-IP-Address.png?resize=700%2C231&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Getting the Raspberry Pi Pico IP Address Thonny IDE\" class=\"wp-image-144655\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-Web-Server-Get-IP-Address.png?w=700&amp;quality=100&amp;strip=all&amp;ssl=1 700w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-Web-Server-Get-IP-Address.png?resize=300%2C99&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/figure><\/div>\n\n\n<p>Open a web browser on your local network and type your Raspberry Pi Pico IP address. The following web page should load.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"716\" height=\"471\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-WebServer-1.png?resize=716%2C471&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Raspberry Pi Pico Basic Web Server on Web Browser\" class=\"wp-image-144656\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-WebServer-1.png?w=716&amp;quality=100&amp;strip=all&amp;ssl=1 716w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-WebServer-1.png?resize=300%2C197&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 716px) 100vw, 716px\" \/><\/figure><\/div>\n\n\n<p>You can click the <em>Light on<\/em> and <em>Light off<\/em> buttons to turn the Raspberry Pi Pico onboard LED on and off.<\/p>\n\n\n\n<div class=\"wp-block-jetpack-tiled-gallery aligncenter is-style-rectangular\"><div class=\"tiled-gallery__gallery\"><div class=\"tiled-gallery__row\"><div class=\"tiled-gallery__col\" style=\"flex-basis:50.00000%\"><figure class=\"tiled-gallery__item\"><img decoding=\"async\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/05\/Raspberry-Pi-Pico-Blinking-LED-Off.jpg?strip=info&#038;w=600&#038;ssl=1 600w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/05\/Raspberry-Pi-Pico-Blinking-LED-Off.jpg?strip=info&#038;w=750&#038;ssl=1 750w\" alt=\"Raspberry Pi Pico W onboard LED off\" data-height=\"422\" data-id=\"130908\" data-link=\"https:\/\/randomnerdtutorials.com\/getting-started-raspberry-pi-pico-w\/raspberry-pi-pico-blinking-led-off\/#main\" data-url=\"https:\/\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/05\/Raspberry-Pi-Pico-Blinking-LED-Off.jpg\" data-width=\"750\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/05\/Raspberry-Pi-Pico-Blinking-LED-Off.jpg?ssl=1\" data-amp-layout=\"responsive\"\/><\/figure><\/div><div class=\"tiled-gallery__col\" style=\"flex-basis:50.00000%\"><figure class=\"tiled-gallery__item\"><img decoding=\"async\" srcset=\"https:\/\/i2.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/05\/Raspberry-Pi-Pico-Blinking-LED-On.jpg?strip=info&#038;w=600&#038;ssl=1 600w, https:\/\/i2.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/05\/Raspberry-Pi-Pico-Blinking-LED-On.jpg?strip=info&#038;w=750&#038;ssl=1 750w\" alt=\"Raspberry Pi Pico W onboard LED on\" data-height=\"422\" data-id=\"130907\" data-link=\"https:\/\/randomnerdtutorials.com\/getting-started-raspberry-pi-pico-w\/raspberry-pi-pico-blinking-led-on\/#main\" data-url=\"https:\/\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/05\/Raspberry-Pi-Pico-Blinking-LED-On.jpg\" data-width=\"750\" src=\"https:\/\/i2.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/05\/Raspberry-Pi-Pico-Blinking-LED-On.jpg?ssl=1\" data-amp-layout=\"responsive\"\/><\/figure><\/div><\/div><\/div><\/div>\n\n\n\n<p>You can also click on the <em>Fetch value<\/em> to request a new random generated value from the Raspberry Pi Pico. It should respond with the web page containing the newest value.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"741\" height=\"490\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/web-server-fetch-value-1.png?resize=741%2C490&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Raspberry Pi Pico Web Server Request a New Value\" class=\"wp-image-144693\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/web-server-fetch-value-1.png?w=741&amp;quality=100&amp;strip=all&amp;ssl=1 741w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/web-server-fetch-value-1.png?resize=300%2C198&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 741px) 100vw, 741px\" \/><\/figure><\/div>\n\n\n<p>You can easily modify the web server to request sensor readings or any other useful information.<\/p>\n\n\n\n<p>The web server is also accessible from your smartphone as long as it is connected to the same network.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"361\" height=\"723\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-Basic-Webserver-Smartphone.png?resize=361%2C723&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Raspberry Pi Pico Web Server on Smarphone\" class=\"wp-image-144695\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-Basic-Webserver-Smartphone.png?w=361&amp;quality=100&amp;strip=all&amp;ssl=1 361w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-Basic-Webserver-Smartphone.png?resize=150%2C300&amp;quality=100&amp;strip=all&amp;ssl=1 150w\" sizes=\"(max-width: 361px) 100vw, 361px\" \/><\/figure><\/div>\n\n\n<p>If you want the Raspberry Pi Pico to run the webserver without being connected to your computer, you need to upload the code as <em>main.py<\/em> to the Raspberry Pi Pico filesystem. For that, after copying the code to a new file, go to <strong>File <\/strong>&gt; <strong>Save as<\/strong> and select <strong>Raspberry Pi Pico<\/strong>.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"214\" height=\"203\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/05\/Save-file-to-Raspberry-Pi-Pico.png?resize=214%2C203&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Save Files to Raspberry Pi Pico Thonny IDE\" class=\"wp-image-130899\"\/><\/figure><\/div>\n\n\n<p>Name the file main.py and click OK to save the file on the Raspberry Pi Pico. Now, it will run the <em>main.py <\/em>file on boot without the need to be connected to the computer.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"545\" height=\"327\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/06\/micropython-main-py-file.png?resize=545%2C327&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Micropython saving main.py file Thonny IDE\" class=\"wp-image-132452\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/06\/micropython-main-py-file.png?w=545&amp;quality=100&amp;strip=all&amp;ssl=1 545w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/06\/micropython-main-py-file.png?resize=300%2C180&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 545px) 100vw, 545px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>In this tutorial, you learned the basics of building a web server with the Raspberry Pi Pico. As an example, we&#8217;ve built a simple page with buttons to control a GPIO and a section to request a new random value from the board.<\/p>\n\n\n\n<p>This is just a basic example for you to understand how building a web server works. The idea is to modify the project to control GPIOs to activate relays, control motors, and display sensor readings or any other useful information.<\/p>\n\n\n\n<p>We hope you&#8217;ve found this tutorial useful.<\/p>\n\n\n\n<p>Learn more about the Raspberry Pi Pico with our eBook:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-w-micropython-ebook\/\" title=\"\">Learn Raspberry Pi Pico with MicroPython (eBook)<\/a><\/li>\n<\/ul>\n\n\n\n<p>If you like the Raspberry Pi Pico, make sure you take a look at other tutorials on our blog:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-w-pinout-gpios\/\">Raspberry Pi Pico and Pico W Pinout Guide: GPIOs Explained<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-outputs-inputs-micropython\/\">Raspberry Pi Pico: Control Digital Outputs and Read Digital Inputs (MicroPython)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-pwm-micropython\/\">Raspberry Pi Pico: PWM Fading an LED (MicroPython)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-dht11-dht22-micropython\/\">Raspberry Pi Pico: DHT11\/DHT22 Temperature and Humidity Sensor (MicroPython)<\/a><\/li>\n<\/ul>\n\n\n\n<p><a href=\"https:\/\/randomnerdtutorials.com\/projects-raspberry-pi-pico\/\">Check out all our Raspberry Pi Pico Guides \u00bb<\/a><\/p>\n\n\n\n<p>Thanks for reading.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this guide, you&#8217;ll learn how to create a basic Raspberry Pi Pico local web server to control outputs and fetch data. As an example, we&#8217;ll create a web page &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"Raspberry Pi Pico: Web Server (MicroPython)\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-web-server-micropython\/#more-144635\" aria-label=\"Read more about Raspberry Pi Pico: Web Server (MicroPython)\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":5,"featured_media":144648,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[324,326],"tags":[],"class_list":["post-144635","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-raspberry-pi-pico","category-raspberry-pi-pico-micropython"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/Raspberry-Pi-Pico-Web-Server-Micropython.jpg?fit=1280%2C720&quality=100&strip=all&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/144635","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/comments?post=144635"}],"version-history":[{"count":12,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/144635\/revisions"}],"predecessor-version":[{"id":154866,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/144635\/revisions\/154866"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/144648"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=144635"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=144635"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=144635"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}