Connecting To The Internet With Pico W
Connecting To The Internet With Pico W
Connecting To The Internet With Pico W
Colophon
Copyright © 2022 Raspberry Pi Ltd
The documentation of the RP2040 microcontroller is licensed under a Creative Commons Attribution-NoDerivatives 4.0
International (CC BY-ND).
build-date: 2022-11-30
build-version: 3a2defe-clean
Throughout the text "the SDK" refers to our Raspberry Pi Pico SDK. More details about the SDK can be
found in the Raspberry Pi Pico C/C++ SDK book. Source code included in the documentation is
Copyright © 2020-2022 Raspberry Pi Ltd (formerly Raspberry Pi (Trading) Ltd.) and licensed under the 3-
Clause BSD license.
RPL reserves the right to make any enhancements, improvements, corrections or any other modifications to the
RESOURCES or any products described in them at any time and without further notice.
The RESOURCES are intended for skilled users with suitable levels of design knowledge. Users are solely responsible for
their selection and use of the RESOURCES and any application of the products described in them. User agrees to
indemnify and hold RPL harmless against all liabilities, costs, damages or other losses arising out of their use of the
RESOURCES.
RPL grants users permission to use the RESOURCES solely in conjunction with the Raspberry Pi products. All other use
of the RESOURCES is prohibited. No licence is granted to any other RPL or other third party intellectual property right.
HIGH RISK ACTIVITIES. Raspberry Pi products are not designed, manufactured or intended for use in hazardous
environments requiring fail safe performance, such as in the operation of nuclear facilities, aircraft navigation or
communication systems, air traffic control, weapons systems or safety-critical applications (including life support
systems and other medical devices), in which the failure of the products could lead directly to death, personal injury or
severe physical or environmental damage (“High Risk Activities”). RPL specifically disclaims any express or implied
warranty of fitness for High Risk Activities and accepts no liability for use or inclusions of Raspberry Pi products in High
Risk Activities.
Raspberry Pi products are provided subject to RPL’s Standard Terms. RPL’s provision of the RESOURCES does not
expand or otherwise modify RPL’s Standard Terms including but not limited to the disclaimers and warranties
expressed in them.
Table of contents
Colophon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Legal disclaimer notice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1. About Raspberry Pi Pico W . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2. Getting on the internet with the C SDK. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.1. Installing the SDK and examples. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.2. Building an SDK example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.3. Creating your own project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.3.1. Going further. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.4. Which hardware am I running on?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3. Getting on the internet with MicroPython . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.1. Getting MicroPython for Raspberry Pi Pico W . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.2. Installing MicroPython on Raspberry Pi Pico W . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.3. Connecting from a Raspberry Pi over USB. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.3.1. Using an integrated development environment (IDE) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.3.2. Remote access via serial port . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.4. The on-board LED . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.5. Installing modules. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.6. Connecting to a wireless network. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.6.1. Connection status codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.6.2. Setting the country. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.6.3. Power-saving mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.7. The MAC address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.8. Making HTTP requests. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.8.1. HTTP with sockets. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.8.2. HTTP with urequests. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.8.3. Ensuring robust connections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.9. Building HTTP servers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.9.1. A simple server for static pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.9.2. Controlling an LED via a web server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.9.3. An asynchronous web server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.10. Running iperf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.11. Which hardware am I running on? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Appendix A: Building MicroPython from source. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Appendix B: Documentation release history . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Table of contents 2
Connecting to the Internet with Raspberry Pi Pico W
Figure 1. The
Raspberry Pi Pico W
Rev3 board.
Raspberry Pi Pico W has been designed to be a low cost yet flexible development platform for RP2040, with the addition
of a 2.4GHz wireless interface and the following key features:
NOTE
Full details of the Raspberry Pi Pico W can be found in the Raspberry Pi Pico W Datasheet.
NOTE
If you have not previously used an RP2040-based board you can get started by reading Getting started with
Raspberry Pi Pico, while further details about the SDK along with API-level documentation can be found in the
Raspberry Pi Pico C/C++ SDK book.
WARNING
If you have not initialised the tinyusb submodule in your pico-sdk checkout, then USB CDC serial, and other USB
functions and example code, will not work as the SDK will contain no USB functionality. Similarly, if you have not
initialised the cyw43-driver and lwip submodules in your checkout, then network-related functionality will not be
enabled.
$ cd pico-examples
$ mkdir build
$ cd build
$ export PICO_SDK_PATH=../../pico-sdk
$ cmake -DPICO_BOARD=pico_w -DWIFI_SSID="Your Network" -DWIFI_PASSWORD="Your Password" ..
Using PICO_SDK_PATH from environment ('../../pico-sdk')
PICO_SDK_PATH is /home/pi/pico/pico-sdk
.
.
.
-- Build files have been written to: /home/pi/pico/pico-examples/build
$
NOTE
The command line flags -DWIFI_SSID="Your Network" -DWIFI_PASSWORD="Your Password" are used by the pico-examples to
set the SSID and password to the call to cyw43_arch_wifi_connect_xxx() to connect to your wireless network.
To then build a basic example for Raspberry Pi Pico W that will scan for nearby wireless networks, you can do:
$ cd pico_w/wifi_scan
$ make
PICO_SDK_PATH is /home/pi/pico-sdk
PICO platform is rp2040.
Build type is Release
PICO target board is pico_w.
.
.
.
[100%] Built target picow_scan_test_background
$
Along with other targets, we have now built a binary called picow_scan_test_background.uf2, which can be dragged onto
the RP2040 USB mass storage device
This binary will scan for wireless networks using the Raspberry Pi Pico W’s wireless chip.
The fastest method to load software onto a RP2040-based board for the first time is by mounting it as a USB mass
storage device. Doing this allows you to drag a file onto the board to program the flash. Go ahead and connect the
Raspberry Pi Pico W to your Raspberry Pi using a micro-USB cable, making sure that you hold down the BOOTSEL
button as you do so, to force it into USB mass storage mode.
If you are running the Raspberry Pi Desktop the Raspberry Pi Pico W should automatically mount as a USB mass
storage device. From here, you can drag-and-drop the UF2 file onto the mass storage device. RP2040 will reboot,
unmounting itself as a mass storage device, and start to run the flashed code.
By default the code will report its results via serial UART.
IMPORTANT
The default UART pins are configured on a per-board basis using board configuration files. The default Raspberry Pi
Pico W UART TX pin (out from Pico W) is pin GP0, and the UART RX pin (in to Pico W) is pin GP1.
To see the text, you will need to enable UART serial communications on the Raspberry Pi host. To do so, run raspi-
config:
$ sudo raspi-config
and go to Interfacing Options → Serial and select "No" when asked "Would you like a login shell to be accessible over
serial?", then "Yes" when asked "Would you like the serial port hardware to be enabled?" You should see something like
Figure 2.
Figure 2. Enabling a
serial UART using
raspi-config on
the Raspberry Pi.
Leaving raspi-config you should choose "Yes" and reboot your Raspberry Pi to enable the serial port.
You should then wire the Raspberry Pi and the Raspberry Pi Pico W together with the following mapping:
See Figure 3.
Figure 3. A Raspberry
Pi 4 and the Raspberry
Pi Pico with UART0
connected together.
Once the two boards are wired together you should install minicom if you have not already done so:
You should see the results of our wireless scanning being printed to the console, see Figure 4.
TIP
Figure 4. Results of
our wireless scanning
in the console
$ ls -la
total 16
drwxr-xr-x 7 aa staff 224 6 Apr 10:41 ./
drwx------@ 27 aa staff 864 6 Apr 10:41 ../
drwxr-xr-x 10 aa staff 320 6 Apr 09:29 pico-examples/
drwxr-xr-x 13 aa staff 416 6 Apr 09:22 pico-sdk/
$ mkdir test
$ cd test
1 #include <stdio.h>
2
3 #include "pico/stdlib.h"
4 #include "pico/cyw43_arch.h"
5
6 char ssid[] = "A Network";①
7 char pass[] = "A Password";②
8
9 int main() {
10 stdio_init_all();
11
12 if (cyw43_arch_init_with_country(CYW43_COUNTRY_UK)) {
13 printf("failed to initialise\n");
14 return 1;
15 }
16 printf("initialised\n");
17
18 cyw43_arch_enable_sta_mode();
19
20 if (cyw43_arch_wifi_connect_timeout_ms(ssid, pass, CYW43_AUTH_WPA2_AES_PSK, 10000)) {
21 printf("failed to connect\n");
22 return 1;
23 }
24 printf("connected\n");
25 }
cmake_minimum_required(VERSION 3.13)
include(pico_sdk_import.cmake)
add_executable(test
test.c
)
pico_enable_stdio_usb(test 1)
pico_enable_stdio_uart(test 1)
pico_add_extra_outputs(test)
Then copy the pico_sdk_import.cmake file from the external folder in your pico-sdk installation to your test project folder,
$ cp ../pico-sdk/external/pico_sdk_import.cmake .
$ cp ../pico-examples/pico_w/lwipopts_examples_common.h lwipopts.h
$ ls -la
total 32
drwxr-xr-x 6 aa staff 192B 29 Jun 18:11 ./
drwxr-xr-x 7 aa staff 224B 29 Jun 16:57 ../
-rw-r--r--@ 1 aa staff 379B 29 Jun 18:10 CMakeLists.txt
-rw-rw-r--@ 1 aa staff 3.3K 15 Jun 00:34 lwipopts.h
-rw-rw-r--@ 1 aa staff 3.1K 15 Jun 00:34 pico_sdk_import.cmake
-rw-r--r--@ 1 aa staff 427B 29 Jun 17:03 test.c
and can build it as we did before with our previous example in the last section.
$ mkdir build
$ cd build
$ export PICO_SDK_PATH=../../pico-sdk
$ cmake -DPICO_BOARD=pico_w ..
$ make
Afterwards unplug your Raspberry Pi Pico W from your computer if it is plugged in already. Then push and hold the
BOOTSEL button while plugging it back into your computer. Then drag and drop the test.uf2 binary onto the RPI-RP2
mass storage volume which will mount on your desktop.
and you should see the a message indicating that the Pico W has connected to your wireless network.
1 #include <stdio.h>
2
3 #include "pico/stdlib.h"
4 #include "hardware/gpio.h"
5 #include "hardware/adc.h"
6
7 int main() {
8 stdio_init_all();
9
10 adc_init();
11 adc_gpio_init(29);
12 adc_select_input(3);
13 const float conversion_factor = 3.3f / (1 << 12);
14 uint16_t result = adc_read();
15 printf("ADC3 value: 0x%03x, voltage: %f V\n", result, result * conversion_factor);
16
17 gpio_init(25);
18 gpio_set_dir(25, GPIO_IN);
19 uint value = gpio_get(25);
20 printf("GP25 value: %i", value);
21 }
cmake_minimum_required(VERSION 3.13)
include(pico_sdk_import.cmake)
add_executable(test
test.c
)
pico_enable_stdio_usb(test 1)
pico_enable_stdio_uart(test 1)
pico_add_extra_outputs(test)
NOTE
If you have not previously used an RP2040-based board you can get started by reading Raspberry Pi Pico Python
SDK book.
Pre-built Binary
A pre-built binary of the latest MicroPython firmware is available from the MicroPython section of the
documentation.
The fastest way to get MicroPython is to download the pre-built release binary from the Documentation pages. If you
can’t or don’t want to use the pre-built release — for example, if you want to develop a C module for MicroPython — you
can follow the instructions in Appendix A> to get the source code for MicroPython, which you can use to build your own
MicroPython firmware binary.
A drive called RPI-RP2 should pop up. Go ahead and drag the MicroPython firmware.uf2 file onto this drive. This
programs the MicroPython firmware onto the flash memory on your Raspberry Pi Pico W.
It should take a few seconds to program the UF2 file into the flash. The board will automatically reboot when finished,
causing the RPI-RP2 drive to disappear, and boot into MicroPython.
When MicroPython boots for the first time, it will sit and wait for you to connect and tell it what to do. You can load a .py
file from your computer onto the board, but a more immediate way to interact with it is through what is called the read-
evaluate-print loop, or REPL.
There are two ways to connect to this REPL; so you can communicate with the MicroPython firmware on your board
over USB, or over the UART serial port on Raspberry Pi Pico W GPIOs.
NOTE
The MicroPython port for RP2040 does not expose a REPL over a UART port by default, please see Raspberry Pi Pico
Python SDK for more details of how to configure MicroPython to allow you to connect to the REPL over UART.
TIP
You can run ls /dev/tty* to list your serial ports. There may be quite a few, but MicroPython’s USB serial will start
with /dev/ttyACM. If in doubt, unplug the micro USB connector and see which one disappears. If you don’t see
anything, you can try rebooting your Raspberry Pi.
$ minicom -o -D /dev/ttyACM0
Where the -D /dev/ttyACM0 is pointing minicom at MicroPython’s USB serial port, and the -o flag essentially means "just do
it". There’s no need to worry about baud rate, since this is a virtual serial port.
Press the enter key a few times in the terminal where you opened minicom. You should see this:
>>>
This is a prompt. MicroPython wants you to type something in, and tell it what to do.
If you press CTRL-D on your keyboard whilst the minicom terminal is focused, you should see a message similar to this:
This key combination tells MicroPython to reboot. You can do this at any time. When it reboots, MicroPython will print
out a message saying exactly what firmware version it is running, and when it was built. Your version number will be
different from the one shown here.
NOTE
If you are working on an Apple Mac, so long as you’re using a recent version of macOS like Catalina, drivers should
already be loaded. Otherwise, see the manufacturers' website for FTDI Chip Drivers. Then you should use a Terminal
program to connect to Serial-over-USB (USB CDC). The serial port will show up as /dev/tty.usbmodem with a number
appended to the end.
If you don’t already have a Terminal program installed you can install minicom using Homebrew:
For full details on how to use the Thonny editor, see the section on using a development environment in the Raspberry
Pi Pico Python SDK book.
With this you can run a script from your local machine directly on Raspberry Pi Pico W.
NOTE
or even:
>>> led.toggle()
to change the current state. However, if you now look at the led object:
>>> led
Pin(WL_GPIO0, mode=OUT)
>>>
which will configure the led object, associate it with the on-board LED and turn the LED on.
NOTE
Full details of the Raspberry Pi Pico W can be found in the Raspberry Pi Pico W Datasheet. WL_GPIO1 is connected to
the PS/SYNC pin on the RT6154A to allow selection of different operating modes, while WL_GPIO2 can be used to
monitor USB VBUS.
1 import network
2 import time
3
4 wlan = network.WLAN(network.STA_IF)
5 wlan.active(True)
6 wlan.connect('Wireless Network', 'The Password')
7
8 while not wlan.isconnected() and wlan.status() >= 0:
9 print("Waiting to connect:")
10 time.sleep(1)
11
12 print(wlan.ifconfig())
although more correctly, you should wait for the connection to succeed or fail in your code, and handle any connection
errors that might occur.
1 import time
2 import network
3
4 ssid = 'Wireless Network'
5 password = 'The Password'
6
7 wlan = network.WLAN(network.STA_IF)
8 wlan.active(True)
9 wlan.connect(ssid, password)
10
11 # Wait for connect or fail
12 max_wait = 10
13 while max_wait > 0:
14 if wlan.status() < 0 or wlan.status() >= 3:
15 break
16 max_wait -= 1
17 print('waiting for connection...')
18 time.sleep(1)
19
20 # Handle connection error
21 if wlan.status() != 3:
22 raise RuntimeError('network connection failed')
23 else:
24 print('connected')
25 status = wlan.ifconfig()
26 print( 'ip = ' + status[0] )
You can also disconnect and then connect to a different wireless network.
For more information on the network.WLAN library see the library documentation.
This can cause problems on some wireless networks. If you find that your Raspberry Pi Pico W does not connect to your
wireless network you may want to try setting the country code, e.g.
>>> rp2.country('GB')
1 import network
2
3 wlan = network.WLAN(network.STA_IF)
4 wlan.active(True)
5 wlan.config(pm = 0xa11140)
1 import network
2 import ubinascii
3
4 wlan = network.WLAN(network.STA_IF)
5 wlan.active(True)
6 mac = ubinascii.hexlify(network.WLAN().config('mac'),':').decode()
7 print(mac)
8
9 # Other things you can query
10 print(wlan.config('channel'))
11 print(wlan.config('essid'))
12 print(wlan.config('txpower'))
NOTE
We have to set the wireless active (which loads the firmware) before we can get the MAC address.
1 # Connect to network
2 import network
3
4 wlan = network.WLAN(network.STA_IF)
5 wlan.active(True)
6 wlan.connect('Wireless Network', 'The Password')
7
8 # Should be connected and have an IP address
9 wlan.status() # 3 == success
10 wlan.ifconfig()
11
12 # Get IP address for google.com
13 import socket
14 ai = socket.getaddrinfo("google.com", 80)
15 addr = ai[0][-1]
16
17 # Create a socket and make a HTTP request
18 s = socket.socket()
19 s.connect(addr)
20 s.send(b"GET / HTTP/1.0\r\n\r\n")
21
22 # Print the response
23 print(s.recv(512))
1 # Connect to network
2 import network
3 wlan = network.WLAN(network.STA_IF)
4 wlan.active(True)
5 wlan.connect('Wireless Network', 'The Password')
6
7 # Make GET request
8 import urequests
9 r = urequests.get("http://www.google.com")
10 print(r.content)
11 r.close()
1 import urequests
2 r = urequests.get("http://www.raspberrypi.com")
3 print(r.status_code) # redirects to https
4 r.close()
NOTE
HTTPS works, but you should be aware that SSL verification is currently disabled.
>>> r = urequests.get("http://date.jsontest.com")
>>> r.json()
{'milliseconds_since_epoch': 1652188199441, 'date': '05-10-2022', 'time': '01:09:59 PM'}
>>>>
IMPORTANT
You must close the returned response object after making a request using the urequests library using
response.close(). If you do not, the object will not be garbage-collected, and if the request is being made inside a loop
this will quickly lead to a crash.
1 import time
2 import network
3 import urequests as requests
4
5 ssid = 'A Network'
Here we handle the possibility that we lose connection to our wireless network and then will seek to reconnect.
1 import network
2 import socket
3 import time
4
5 from machine import Pin
6
7 led = Pin(15, Pin.OUT)
8
9 ssid = 'A Network'
10 password = 'A Password'
11
12 wlan = network.WLAN(network.STA_IF)
13 wlan.active(True)
14 wlan.connect(ssid, password)
15
16 html = """<!DOCTYPE html>
17 <html>
18 <head> <title>Pico W</title> </head>
19 <body> <h1>Pico W</h1>
20 <p>Hello World</p>
21 </body>
22 </html>
23 """
24
25 # Wait for connect or fail
26 max_wait = 10
27 while max_wait > 0:
28 if wlan.status() < 0 or wlan.status() >= 3:
29 break
30 max_wait -= 1
31 print('waiting for connection...')
32 time.sleep(1)
33
34 # Handle connection error
35 if wlan.status() != 3:
36 raise RuntimeError('network connection failed')
37 else:
38 print('connected')
39 status = wlan.ifconfig()
40 print( 'ip = ' + status[0] )
41
42 # Open socket
43 addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
44
45 s = socket.socket()
46 s.bind(addr)
47 s.listen(1)
48
49 print('listening on', addr)
50
51 # Listen for connections
52 while True:
53 try:
54 cl, addr = s.accept()
55 print('client connected from', addr)
56 cl_file = cl.makefile('rwb', 0)
57 while True:
58 line = cl_file.readline()
NOTE
This example is synchronous, for more robust request handling you should implement the server to handle requests
asynchronously.
Figure 5. The
Raspberry Pi Pico W
with an LED on GP15.
Connecting an LED to GP15 we can turn the LED on and off by using HTTP GET. We can do this by going to
http://192.168.1.X/light/on to turn the LED on, and http://192.168.1.X/light/off to turn the LED off, in our web browser;
where 192.168.1.X is the IP address of our Pico W, which will be printed in the console after it connects to the network.
1 import network
2 import socket
3 import time
4
5 from machine import Pin
6
7 led = Pin(15, Pin.OUT)
8
9 ssid = 'A Network'
10 password = 'A Password'
11
12 wlan = network.WLAN(network.STA_IF)
13 wlan.active(True)
14 wlan.connect(ssid, password)
15
16 html = """<!DOCTYPE html>
17 <html>
18 <head> <title>Pico W</title> </head>
19 <body> <h1>Pico W</h1>
20 <p>%s</p>
21 </body>
22 </html>
23 """
24
25 # Wait for connect or fail
26 max_wait = 10
27 while max_wait > 0:
28 if wlan.status() < 0 or wlan.status() >= 3:
29 break
30 max_wait -= 1
31 print('waiting for connection...')
32 time.sleep(1)
33
34 # Handle connection error
35 if wlan.status() != 3:
36 raise RuntimeError('network connection failed')
37 else:
38 print('connected')
39 status = wlan.ifconfig()
40 print( 'ip = ' + status[0] )
41
42 # Open socket
43 addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
44
45 s = socket.socket()
46 s.bind(addr)
47 s.listen(1)
48
49 print('listening on', addr)
50
51 # Listen for connections
52 while True:
53 try:
54 cl, addr = s.accept()
55 print('client connected from', addr)
56 request = cl.recv(1024)
57 print(request)
58
59 request = str(request)
60 led_on = request.find('/light/on')
61 led_off = request.find('/light/off')
62 print( 'led on = ' + str(led_on))
63 print( 'led off = ' + str(led_off))
64
65 if led_on == 6:
66 print("led on")
67 led.value(1)
68 stateis = "LED is ON"
69
70 if led_off == 6:
71 print("led off")
72 led.value(0)
73 stateis = "LED is OFF"
74
75 response = html % stateis
76
1 import network
2 import socket
3 import time
4
5 from machine import Pin
6 import uasyncio as asyncio
7
8 led = Pin(15, Pin.OUT)
9 onboard = Pin("LED", Pin.OUT, value=0)
10
11 ssid = 'A Network'
12 password = 'A Password'
13
14 html = """<!DOCTYPE html>
15 <html>
16 <head> <title>Pico W</title> </head>
17 <body> <h1>Pico W</h1>
18 <p>%s</p>
19 </body>
20 </html>
21 """
22
23 wlan = network.WLAN(network.STA_IF)
24
25 def connect_to_network():
26 wlan.active(True)
27 wlan.config(pm = 0xa11140) # Disable power-save mode
28 wlan.connect(ssid, password)
29
30 max_wait = 10
31 while max_wait > 0:
32 if wlan.status() < 0 or wlan.status() >= 3:
33 break
34 max_wait -= 1
35 print('waiting for connection...')
36 time.sleep(1)
37
38 if wlan.status() != 3:
39 raise RuntimeError('network connection failed')
40 else:
41 print('connected')
42 status = wlan.ifconfig()
43 print('ip = ' + status[0])
44
45 async def serve_client(reader, writer):
46 print("Client connected")
47 request_line = await reader.readline()
48 print("Request:", request_line)
49 # We are not interested in HTTP request headers, skip them
50 while await reader.readline() != b"\r\n":
51 pass
52
53 request = str(request_line)
54 led_on = request.find('/light/on')
55 led_off = request.find('/light/off')
56 print( 'led on = ' + str(led_on))
57 print( 'led off = ' + str(led_off))
58
59 stateis = ""
60 if led_on == 6:
61 print("led on")
62 led.value(1)
63 stateis = "LED is ON"
64
65 if led_off == 6:
66 print("led off")
67 led.value(0)
68 stateis = "LED is OFF"
69
70 response = html % stateis
71 writer.write('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
72 writer.write(response)
73
74 await writer.drain()
75 await writer.wait_closed()
76 print("Client disconnected")
77
78 async def main():
79 print('Connecting to Network...')
80 connect_to_network()
81
82 print('Setting up webserver...')
83 asyncio.create_task(asyncio.start_server(serve_client, "0.0.0.0", 80))
84 while True:
85 onboard.on()
86 print("heartbeat")
87 await asyncio.sleep(0.25)
88 onboard.off()
89 await asyncio.sleep(5)
90
91 try:
92 asyncio.run(main())
93 finally:
94 asyncio.new_event_loop()
NOTE
1 import network
2 if hasattr(network, "WLAN"):
3 # the board has WLAN capabilities
Alternatively, you can inspect the MicroPython firmware version to check whether it was compiled for Raspberry Pi Pico
or for Pico W using the sys module.
So if 'Pico W' in sys.implementation._machine can be used to detect whether your firmware was compiled for Pico W.
$ mkdir pico_w
$ cd pico_w
$ git clone https://github.com/micropython/micropython.git --branch master
$ git clone https://github.com/micropython/micropython-lib.git --branch master
NOTE
Putting micropython-lib side-by-side with your MicroPython checkout will mean that it is automatically pulled into
your MicroPython build, and libraries in micropython-lib will be "pre-added" to the list of modules available by default
on your Pico W device.
$ cd micropython
$ make -C ports/rp2 BOARD=PICO_W submodules
$ make -C mpy-cross
$ cd ports/rp2
$ make BOARD=PICO_W
If everything went well, there will be a new directory called build-PICO_W (that’s ports/rp2/build-PICO_W relative to the top-
level micropython directory), which contains the new firmware binaries. Drag and drop the firmware.uf2 onto the RPI-RP2
drive that pops up once your Raspberry Pi Pico W is in BOOTSEL mode.