Once you have CircuitPython setup and libraries installed we can get your board connected to the Internet.
To get connected, you will need to start by creating a secrets file.
What's a secrets file?
We expect people to share tons of projects as they build CircuitPython WiFi widgets. What we want to avoid is people accidentally sharing their passwords or secret tokens and API keys. So, we designed all our examples to use a secrets.py file, that is in your CIRCUITPY drive, to hold secret/private/custom data. That way you can share your main project without worrying about accidentally sharing private stuff.
Your secrets.py file should look like this:
# This file is where you keep secret settings, passwords, and tokens! # If you put them in the code you risk committing that info or sharing it secrets = { 'ssid' : 'home ssid', 'password' : 'my password', 'timezone' : "America/New_York", # http://worldtimeapi.org/timezones }
Inside is a python dictionary named secrets with a line for each entry. Each entry has an entry name (say 'ssid'
) and then a colon to separate it from the entry key 'home ssid'
and finally a comma ,
At a minimum you'll need the ssid
and password
for your local WiFi setup. As you make projects you may need more tokens and keys, just add them one line at a time. Other non-secret data like your timezone can also go here, just because it's called secrets doesn't mean you can't have general customization data in there!
For the correct time zone string, look at http://worldtimeapi.org/timezones and remember that if your city is not listed, look for a city in the same time zone, for example Boston, New York, Philadelphia, Washington DC, and Miami are all on the same time as New York.
Of course, don't share your secrets.py - keep that out of GitHub, Discord or other project-sharing sites.
Connect to WiFi
OK now you have your secrets setup - you can connect to the Internet using the ESP32SPI and the Requests modules.
First, make sure you are running the latest version of Adafruit CircuitPython for your board.
Before continuing make sure your board's lib folder or root filesystem has the above files copied over:
- adafruit_bus_device
- adafruit_minimqtt
- adafruit_io
- adafruit_esp32_spi
- adafruit_requests
Connect to the board's serial REPL via Mu so you are at the CircuitPython >>> prompt. Once that's done, load up the following example in Mu and save it to the Pico as code.py.
# SPDX-FileCopyrightText: 2019 ladyada for Adafruit Industries # SPDX-License-Identifier: MIT from os import getenv import board import busio from digitalio import DigitalInOut import adafruit_connection_manager import adafruit_requests from adafruit_esp32spi import adafruit_esp32spi # Get wifi details and more from a settings.toml file # tokens used by this Demo: CIRCUITPY_WIFI_SSID, CIRCUITPY_WIFI_PASSWORD secrets = { "ssid": getenv("CIRCUITPY_WIFI_SSID"), "password": getenv("CIRCUITPY_WIFI_PASSWORD"), } if secrets == {"ssid": None, "password": None}: try: # Fallback on secrets.py until depreciation is over and option is removed from secrets import secrets except ImportError: print("WiFi secrets are kept in settings.toml, please add them there!") raise print("Raspberry Pi RP2040 - ESP32 SPI webclient test") TEXT_URL = "http://wifitest.adafruit.com/testwifi/index.html" JSON_URL = "http://api.coindesk.com/v1/bpi/currentprice/USD.json" # Raspberry Pi RP2040 Pinout esp32_cs = DigitalInOut(board.GP13) esp32_ready = DigitalInOut(board.GP14) esp32_reset = DigitalInOut(board.GP15) spi = busio.SPI(board.GP10, board.GP11, board.GP12) esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) pool = adafruit_connection_manager.get_radio_socketpool(esp) ssl_context = adafruit_connection_manager.get_radio_ssl_context(esp) requests = adafruit_requests.Session(pool, ssl_context) if esp.status == adafruit_esp32spi.WL_IDLE_STATUS: print("ESP32 found and in idle mode") print("Firmware vers.", esp.firmware_version) print("MAC addr:", [hex(i) for i in esp.MAC_address]) for ap in esp.scan_networks(): print("\t%s\t\tRSSI: %d" % (ap.ssid, ap.rssi)) print("Connecting to AP...") while not esp.is_connected: try: esp.connect_AP(secrets["ssid"], secrets["password"]) except OSError as e: print("could not connect to AP, retrying: ", e) continue print("Connected to", esp.ap_info.ssid, "\tRSSI:", esp.ap_info.rssi) print("My IP address is", esp.ipv4_address) print( "IP lookup adafruit.com: %s" % esp.pretty_ip(esp.get_host_by_name("adafruit.com")) ) print("Ping google.com: %d ms" % esp.ping("google.com")) # esp._debug = True print("Fetching text from", TEXT_URL) r = requests.get(TEXT_URL) print("-" * 40) print(r.text) print("-" * 40) r.close() print() print("Fetching json from", JSON_URL) r = requests.get(JSON_URL) print("-" * 40) print(r.json()) print("-" * 40) r.close() print("Done!")
Once all the files are copied from your computer to the Pico, you should have the following files on your CIRCUITPY drive.
The code should run and you should get something like the following in your serial window:
In order, the example code:
Initializes the ESP32 over SPI using the SPI port and 3 control pins.
# Raspberry Pi RP2040 Pinout esp32_cs = DigitalInOut(board.GP13) esp32_ready = DigitalInOut(board.GP14) esp32_reset = DigitalInOut(board.GP15) spi = busio.SPI(board.GP10, board.GP11, board.GP12) esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
This tells the requests
library the type of socket being used (socket type varies by connectivity type - this is using the adafruit_esp32spi_socket
for the example). It also sets the interface to an esp
object. This is a little bit of a hack, but it lets the code use requests
like CPython does.
requests.set_socket(socket, esp)
Verifies an ESP32 is found, checks the firmware and MAC address
if esp.status == adafruit_esp32spi.WL_IDLE_STATUS: print("ESP32 found and in idle mode") print("Firmware vers.", esp.firmware_version) print("MAC addr:", [hex(i) for i in esp.MAC_address])
Performs a scan of all access points it can see and prints out the name and signal strength:
for ap in esp.scan_networks(): print("\t%s\t\tRSSI: %d" % (str(ap['ssid'], 'utf-8'), ap['rssi']))
Connects to the AP defined here, then prints out the local IP address, attempts to do a domain name lookup and ping google.com to check network connectivity (note sometimes the ping fails or takes a while, this isn't a big deal).
print("Connecting to AP...") esp.connect_AP(b'MY_SSID_NAME', b'MY_SSID_PASSWORD') print("Connected to", str(esp.ssid, 'utf-8'), "\tRSSI:", esp.rssi) print("My IP address is", esp.pretty_ip(esp.ip_address)) print("IP lookup adafruit.com: %s" % esp.pretty_ip(esp.get_host_by_name("adafruit.com"))) print("Ping google.com: %d ms" % esp.ping("google.com"))
OK to get to the really interesting part. With a large-RAM (well, over 32 KB) device like the Pico, a lot of neat tricks can be done. For example you can implement an interface a lot like requests - which makes getting data really really easy.
To read in all the text from a web URL call requests.get
- you can pass in https
URLs for SSL connectivity
TEXT_URL = "http://wifitest.adafruit.com/testwifi/index.html" print("Fetching text from", TEXT_URL) r = requests.get(TEXT_URL) print('-'*40) print(r.text) print('-'*40) r.close()
Or, if the data is in structured JSON, you can get the json pre-parsed into a Python dictionary that can be easily queried or traversed. (Again, only for Pico, nRF52840, M4 and other high-RAM boards)
JSON_URL = "http://api.coindesk.com/v1/bpi/currentprice/USD.json" print("Fetching json from", JSON_URL) r = requests.get(JSON_URL) print('-'*40) print(r.json()) print('-'*40) r.close()
Text editor powered by tinymce.